Add sqlite-vec plugin to Python server store#247
Add sqlite-vec plugin to Python server store#247javiermtorres wants to merge 18 commits intomainfrom
Conversation
|
@copilot check if conflicts can be solved easily |
…k/python/src/cq/store.py - Remove Python MCP server (deleted on main, replaced by Go CLI) - Port sqlite-vec and sentence-transformers additions to the new sdk/python/src/cq/store.py location (renamed from local_store.py) - Port test additions to sdk/python/tests/test_store.py - Add sqlite-vec and sentence-transformers deps to sdk/python/pyproject.toml - Resolve uv.lock conflict (pygments 2.19.2 -> 2.20.0) - Remove sqlite-vec from team-api/pyproject.toml (deleted, now server/backend) Co-authored-by: javiermtorres <4608715+javiermtorres@users.noreply.github.com>
Conflicts resolved in f7e3464. Here's what was needed:
Also added |
|
@copilot rebase from origin/main and solve conflicts. |
* Document tier model in READMEs and cq-status plugin Adds a "Knowledge tiers" section to the top README explaining what local, private, and public mean and where knowledge units land when propose is called with or without a remote configured. Shorter blocks in the CLI README, Go SDK README, and Python SDK README link back to the canonical explanation. The cq-status plugin command doc prints a one-line tier legend directly under the tier counts. Fixes #246. * Use SDK-consistent symbol names in tier docs Match the surrounding Quick Start vocabulary: the Python SDK section now uses `cq.propose(...)` (the Quick Start instance is named `cq`, not `client`), and the Go SDK section qualifies the returned tier constants as `cq.Private` / `cq.Local` to match the preceding sentence. Co-authored-by: peteski22 <487783+peteski22@users.noreply.github.com>
plugins/cq/uv.lock was left at version 0.5.0 in 556c2ba ("Bump plugin to 0.6.0", #239) because the lockfile was not regenerated alongside pyproject.toml. The existing uv-lock pre-commit hook in the root config never fired because its default files regex is anchored to the repo root and cq has no root pyproject.toml (three independent uv sub-projects, no workspace). The same inert hook existed in sdk/python/.pre-commit-config.yaml. Regenerate plugins/cq/uv.lock so it matches the bumped 0.6.0 version. Add two layers of drift protection covering all three Python sub-projects (plugins/cq, sdk/python, server/backend): - Switch the lint-plugin, lint-sdk-python, and lint-server-backend Make targets to invoke uv run --locked. uv run silently regenerates a stale lockfile before any wrapped command sees it, so without --locked no downstream check could ever fail in CI. --locked makes uv abort with a clear error message instead, and CI runs the Make targets directly. - Replace the inert upstream uv-lock hook with three local pre-commit hooks that invoke uv lock --check --directory <subdir>. These fire at git commit time (when pre-commit is invoked outside of uv run) for any change touching a sub-project's pyproject.toml or uv.lock, giving early feedback before the change leaves the developer's machine. Co-authored-by: peteski22 <487783+peteski22@users.noreply.github.com>
* Clarify recent additions are local-only in cq-status When a remote is configured, Client.Propose writes directly to the remote and Client.Status fills the recent slice from the local store only, so users who only propose against a remote saw an empty "Recent Additions" section without context. Rename the section to "Recent Local Additions" in the slash command, add explicit guidance to render "(no recent local additions)" when the slice is empty, and update the status MCP tool description so it reflects that tier counts and domains aggregate across local and remote while recent additions and confidence distribution are local only. Closes #245. * Qualify Propose fallback note in cq-status doc The existing wording claimed proposed units always go to the remote when one is configured, but Client.Propose falls back to local storage when the remote is unreachable. Note that the remote must be both configured and reachable for units to bypass the local recent list. Co-authored-by: peteski22 <487783+peteski22@users.noreply.github.com>
* Merge remote domain counts into client Status() * Cover remote domain count merge in Status() tests Add regression tests for both SDKs asserting that Client.Status() merges remote /stats domain counts into StoreStats.domain_counts, accumulating counts where a domain appears in both local and remote. sdk/go: TestStatusWithRemoteMergesDomainCounts sdk/python: test_status_merges_remote_domain_counts * Isolate TestDrain from host CQ_* environment variables TestDrain was the only test in sdk/go/client_test.go that constructed a Client directly without first calling testClearEnv(t). A host shell with CQ_ADDR set would cause the "local-only" seeding client to hit the real remote, leaving the local store empty and failing the drain assertions. --------- Co-authored-by: Peter Wilson <peter@mozilla.ai> Co-authored-by: peteski22 <487783+peteski22@users.noreply.github.com>
feat(installer): multi-host installer for Cursor, Windsurf, OpenCode, and Claude
Replace the legacy OpenCode-only shell installer with a stdlib-only Python installer at scripts/install/ supporting four hosts. Drops jq as a prerequisite.
Installer core:
- Idempotent primitives for JSON merge, hook entries, Markdown blocks,
manifest-tracked file copies, and symlinks. --dry-run across all.
- Per-host adapters under cq_install/hosts/ with a shared RunState for
dedup (shared skills installed once, binary fetched once).
- Config write hardening: malformed JSON, non-dict leaves, and
unexpected hook shapes raise clear errors naming the file.
Binary management:
- New plugins/cq/scripts/cq_binary.py (stdlib-only) owns the binary
download, version check, and cache logic. Single source of truth
consumed by both the Claude plugin bootstrap and the installer.
- Non-Claude hosts invoke the cq binary directly for MCP, fixing
startup timeouts on Windows caused by Python stdio buffering.
- bootstrap.py shrinks to a thin Claude-only launcher.
Hosts:
- Cursor: mcp.json, rules/cq.mdc, four lifecycle hooks with
platform-aware shell escaping, shared runtime hook script.
- Windsurf: mcp_config.json, shared skills.
- OpenCode: opencode.json with schema seeding, AGENTS.md block,
generated commands with user-edit protection on uninstall.
- Claude: thin marketplace wrapper (add/install/remove).
Build:
- Makefile targets for all hosts plus install-all/uninstall-all.
- PowerShell wrapper for Windows.
- Installer CI workflow, pre-commit ty and uv-lock checks.
Co-authored-by: Jonathan Kingston (#166)
Closes #154
Co-authored-by: peteski22 <487783+peteski22@users.noreply.github.com>
Add author, repository, license, and keywords to plugin.json. Remove duplicated version from marketplace.json since plugin.json is authoritative. Bump CLI version pin to 0.2.1 in bootstrap.json. Update test fixtures to match. Co-authored-by: peteski22 <487783+peteski22@users.noreply.github.com>
Commit 3454b2e squash-merged PR #254 with a malformed co-author trailer. This empty commit corrects the attribution for Jonathan Kingston's contribution to the multi-host installer (see #166). Co-authored-by: Jonathan Kingston <338988+jonathanKingston@users.noreply.github.com> Co-authored-by: peteski22 <487783+peteski22@users.noreply.github.com>
Replace the v0.0.0 placeholder with the actual tagged version. The replace directive remains because the SDK module proxy copy is missing embedded skill.md (see #259). Co-authored-by: peteski22 <487783+peteski22@users.noreply.github.com>
The previous pin was stale; the server imports cq.models for shared Pydantic schemas which are current in sdk/python/0.6.1. Co-authored-by: peteski22 <487783+peteski22@users.noreply.github.com>
The skill description is what Claude sees in the available skills list to decide whether to invoke it. The previous description explained what cq is rather than when to use it, causing Claude to skip activation. Rewrite the description as an imperative trigger that makes querying unconditional, names the blind-spot failure mode (stale training data), and lists the full per-task loop (query, propose, confirm/flag). Co-authored-by: peteski22 <487783+peteski22@users.noreply.github.com>
* Commit SKILL.md in SDKs for module proxy completeness The Go and Python SDK copies of the plugin skill prompt were gitignored and generated at build time. This left the Go module proxy copy incomplete, breaking go get/go install for external consumers. Commit the SKILL.md copies (renamed from skill.md to match the source), remove them from .gitignore, and add sync enforcement via per-SDK check-skill-sync Makefile targets and a dedicated CI workflow that blocks merges when copies drift from the plugin source. Fixes #259 * Address review: check-skill-sync as gatekeeper, not sync-skill Replace sync-skill with check-skill-sync as the dependency of lint and test in both SDK Makefiles, matching the check-notice pattern. Drift now fails the build instead of being silently fixed. Add root-level sync-skill target so the error message guidance works from any directory. Co-authored-by: peteski22 <487783+peteski22@users.noreply.github.com>
The Go module proxy now has a complete copy of the SDK (sdk/go/v0.2.2 includes the committed SKILL.md), so the local replace directive is no longer needed. This unblocks go install for external consumers. The replace directive is kept commented out for local monorepo development convenience. Co-authored-by: peteski22 <487783+peteski22@users.noreply.github.com>
) * Replace exact cli_version check with cli_min_version >= comparison The plugin bootstrap previously required an exact CLI version match, forcing a plugin release for every CLI bump even when the contract hadn't changed. Switch to a minimum version (>=) comparison using tuple-based semver so the plugin only needs updating when it genuinely requires a newer CLI feature. Renames: check_version -> meets_min_version, load_required_version -> load_min_version. * Address review feedback: show actual binary version and rename variable Report the actual cached binary version (not the minimum) in installer output when the binary is already valid. Rename the leftover required_version variable in bootstrap.py to min_version. Co-authored-by: peteski22 <487783+peteski22@users.noreply.github.com>
Co-authored-by: peteski22 <487783+peteski22@users.noreply.github.com>
Co-authored-by: peteski22 <487783+peteski22@users.noreply.github.com>
This file was incorrectly modified by a prior merge commit. Restoring to the version from main (revision=3 with upload-time metadata fields). Co-authored-by: peteski22 <487783+peteski22@users.noreply.github.com>
Done in 45f715e. The branch is now rebased on origin/main — the diff from main contains exactly our 3 intended files:
Also fixed an unintended regression where |
|
Since the SDK and server stores were split at some point during the development of this PR, the agent tried to reconcile changes and this resulted in unwanted functionality. |
Adds semantic similarity search to the local knowledge store using sqlite-vec and
sentence-transformers.Changes Made
sdk/python/src/cq/store.py: Added sqlite-vec virtual table (knowledge_units_vec) andSentenceTransformerembedding model support toLocalStore. Embeddings are generated on insert/update and used for vector similarity search inquery().sdk/python/tests/test_store.py: Addedembedding_modelpytest fixture and updated allLocalStoreconstructor calls to pass the embedding model.sdk/python/pyproject.toml: Addedsqlite-vec==0.1.7a10andsentence-transformers[onnx]as dependencies.