CLI tool for managing knowledge and documentation in Git + Markdown. Sync, search (full-text + vector), AI assistance, task tracking, and traceability between documentation and code β all in one binary, no servers or databases.
# Debug
just build
# Release
just releasecargo run -- <command> [args]
./target/release/kqs <command>just test
cargo test --workspace -- --nocapturekqs runs in two contexts:
| Mode | Description | Commands |
|---|---|---|
Dev (--dev) |
Inside a developer's project. Reads code, does not write to docs | scan, check, watch |
Doc (--doc) |
Inside a knowledge repository. Full access | everything + doc new, typespec, readme |
# Explicit
kqs --dev check scan
kqs --doc doc new adr "Title"
# Auto-detect: if docs/ + TypeSpec/ exist β doc mode
kqs check traceability
# Via env
KQS_MODE=dev kqs check scanIn dev mode, doc-only commands (kqs doc new, kqs typespec new, kqs readme)
fail with an explanatory error.
# Create a knowledge repository
kqs init
kqs init --path ~/my-knowledge --remote https://github.com/user/knowledge.git# List templates
kqs doc template --list
# Create a document
kqs doc new adr "Database Choice" # β docs/03-architecture/adr-001-*.md
kqs doc new tz "API Gateway Design" # β docs/04-technical-design/tz-001-*.md
kqs doc new bft "Customer Portal" # β docs/01-business-foundation/bft-001-*.md
kqs doc new frd "Sign-up" # β docs/02-product-ux/frd-001-*.md
# Screen and User Flow
kqs screen "Login Screen"
kqs userflow "Onboarding Flow"
# List all documents
kqs doc listEvery template in .kqs/templates/ carries a specific semantic load β the type is chosen
by what question the document answers, not by preference. The types form a chain:
each next type refines the previous one, from business intent down to the data
specification that code implements.
| Type | Category | What this document does | Example |
|---|---|---|---|
idea |
Ideas | Unvalidated thought: problem statement, proposed solution, impact, effort estimate | "Push notifications will increase retention" |
bft |
Business Foundation | Business-functional foundation: objectives, stakeholders, scope (in/out). The root of the chain β what the business wants and why | BFT-001 "User Authentication" |
brd |
Business Foundation | Business requirements: what the business needs, priorities, assumptions, constraints, acceptance criteria | BR-001: "Payments must support card and SBP" |
frd |
Product & UX | Functional requirements: how the system behaves β UI, business rules, data, error handling | FR-002: "Login form must validate email format" |
nfr |
Business Foundation | Non-functional requirements: performance, security, availability, scalability | "p95 < 300 ms; TLS everywhere" |
user_story |
Product & UX | User story: As a / I want / so that, acceptance criteria | "As a user, I want to reset my password so that I can regain access" |
adr |
Architecture | Recorded architectural decision: context, decision, consequences, alternatives considered | ADR-001: "Store JWT in Keychain" |
rfc |
Architecture | Proposal for discussion before committing: motivation, detailed design, alternatives, open questions | RFC: "Migrate REST β GraphQL" |
tz |
Technical Design | Technical design: architecture, API, data model, implementation plan, testing strategy | TZ-001: "API Gateway design" |
screen |
Technical Design | Single screen: layout, components, states (loading/empty/error), interactions | "Login screen" |
userflow |
Technical Design | End-to-end flow: steps, decision points, error paths, success criteria | "Onboarding flow" |
glossary |
Glossary | Term definition, context, related terms | "Idempotency" |
typespec |
TypeSpec | Data specification (TypeSpec model) β the terminal link before code | TypeSpec/User.tsp |
Create documents in this order β each type flows from the previous one:
idea β bft β brd/frd/nfr β adr β rfc β tz β typespec β code
- idea β a thought worth exploring. Once validated, formalize it into a
bft. - bft β the root of the chain: what the business wants and why (objectives, stakeholders, scope). Example: "User Authentication".
- brd / frd / nfr β derived from the
bft: business, functional and non-functional requirements that detail it. - adr β an architectural decision made to satisfy those requirements: context, decision, consequences.
- rfc β a proposal for a significant change, discussed before it becomes a final design.
- tz β the technical design that fixes the decision in concrete terms: architecture, API, data model.
- typespec β the data specification: models the design as checkable
TypeSpeccontracts. - code β implements the specification, linked back via
@doc-anchor.
kqs check traceability-deep verifies the chain is complete (BFT β ADR β TZ β TypeSpec),
flagging any missing link.
# Create a model
kqs typespec new User
# β TypeSpec/User.tsp, updated TypeSpec/main.tsp
# List models
kqs typespec list
# β Name File Doc Refs
# β User User.tsp TZ-001# Full report
kqs check traceability
# β Table: Object, Type, Status, Links, Recommendation
# Orphans (TypeSpec without documentation)
kqs check orphans# Full chain BFT β FRD β ADR β TZ β TypeSpec
kqs check traceability-deep --deep
# Custom chain
kqs check traceability-deep --deep --chain "bft adr tz"
# JSON for editor plugins
kqs check traceability-deep --deep --jsonDeep coverage matrix:
- β covered β full chain β broken β chain gap
- π» orphan β no incoming links πΈοΈ stale β doc changed, code not updated
# Scan projects from the config for @doc-anchor
kqs check scan
# Rebuild the graph before scanning
kqs check scan --rebuildWhen an orphan anchor is found (@doc-anchor PushNotificationManager without TypeSpec),
a TASK with instructions is created automatically.
# All stale links
kqs check notify
# Last 7 days
kqs check notify --since 7dknowledge_path = "."
[[projects]]
path = "../mobile-app"
label = "iOS App"
[[projects]]
path = "../backend"
label = "Backend"
[watcher]
debounce_secs = 600
ignore_patterns = []
[search]
chunk_size = 512
chunk_overlap = 64
max_results = 10
relevance_threshold = 0.7# Regenerate
kqs readmeGenerates between the <!-- kqs:start --> / <!-- kqs:end --> markers:
- Kanban Board β tasks by status (todo/in_progress/review/done)
- Table of Contents β document tree with clickable links
Updated automatically on kqs push and kqs watch.
kqs task new --title "Implement search" --priority high
kqs task list
kqs task status TASK-001 --set in_progress
kqs task show TASK-001
kqs task search "search"# Full-text (FTS5, always available)
kqs search "system architecture"
# Vector (sqlite-vec + Candle, when a model is available)
kqs search --vector "semantic search"
# Hybrid (default)
kqs search "database" --limit 20# Auto-commit changes
kqs watch
# Custom debounce
kqs watch --debounce-secs 120
# Trace daemon: watcher + auto-trace on every cycle
kqs watch --tracekqs push # pull --rebase β readme-gen β push
kqs push --no-readme # skip README generation
kqs push --dry-run # show changes without pushingDevelopers annotate code in their projects:
// @doc-anchor SecureTokenStorage
// @see docs://architecture/ADR-001.md
class KeychainStorage: TokenStorable { }// @doc-anchor AuthServiceImpl
func ValidateToken(token string) bool { }When scanning, kqs finds these annotations and builds the graph:
BFT-001 β ADR-001 β TZ-001 β TypeSpec β @doc-anchor β code
Orphan anchors (anchor exists, no TypeSpec) β task created automatically.
kqs conflict list
kqs conflict show docs/architecture.md
kqs conflict resolve docs/architecture.md --ours
kqs conflict resolve docs/architecture.md --theirskqs ask "How is the architecture organized?"
kqs ask "Describe the User model" --insert docs/user-model.mdRequires an LLM provider in knowledge.toml (Ollama/OpenAI/Anthropic).
just lint # clippy
just fmt # fmt --check
just fmt-fix # fmt
just check # build + lint + test + fmt# On every push/PR β build + clippy + test for macOS/Linux/Windows
.github/workflows/ci.yml
# On tag v* β release build for 3 platforms + GitHub Release
.github/workflows/release.yml
# On tag v* β publish all workspace crates to crates.io
.github/workflows/publish.yml# From crates.io (installs the `kqs` binary)
cargo install kqs
# From source
cargo install --path kqs
kqs --helpNote on the name: the crates.io package
kqis an unrelated KDL query tool. Our package iskqsand installs thekqsbinary β no conflict with anything on crates.io.
Or download a binary from GitHub Releases.
Workspace crates are published to crates.io from a v* tag:
just bump-version 0.2.0β bump the single workspace version inCargo.toml- Commit and push the tag
v0.2.0(must match the workspace version) - CI runs tests, then publishes
kq-configβkq-llmβkq-embeddingsβkq-coreβkqsin dependency order just publish-checkβ local pre-flight: dry-run publish of the leaf crates and a package file audit of the dependents
Requires the CARGO_REGISTRY_TOKEN secret in GitHub repository settings.
kqs/ # CLI entry point (clap)
kq-core/ # Business logic
βββ check.rs # Traceability, orphans, deep coverage
βββ code_anchor.rs # @doc-anchor scanner
βββ db.rs # SQLite: files, trace_nodes, trace_links, code_anchors
βββ docs.rs # DocType, DocNode, front-matter parser
βββ git.rs # Git operations
βββ readme_gen.rs # README generator (Kanban + TOC)
βββ task.rs # CRDT tasks
βββ typespec.rs # TypeSpec models
βββ watcher.rs # File watcher
kq-embeddings/ # Candle + all-MiniLM-L6-v2
kq-llm/ # Ollama, OpenAI, Anthropic providers
kq-config/ # knowledge.toml parsing
<project>/
βββ .kqs/
β βββ knowledge.toml # config
β βββ knowledge.db # SQLite: FTS + vectors + trace graph
β βββ events/ # CRDT task events
β βββ templates/ # document templates
βββ users/ # users (username.md)
βββ docs/ # documentation (8 categories)
βββ tasks/ # tasks (TASK-NNN.md)
βββ TypeSpec/ # TypeSpec models
βββ README.md # auto-Kanban + Table of Contents
Tasks use CRDT events instead of overwrites:
create β .kqs/events/TASK-001/20260709T100000Z-create.md
assign alex β .kqs/events/TASK-001/20260709T110000Z-assign-alex.md
move review β .kqs/events/TASK-001/20260709T120000Z-move-review.md
Why: no merge conflicts, status is computed by replay, readable git diff, parallel work without collisions.
Alice: kqs task assign TASK-001 alex β ...assign-alex.md
Bob: kqs task assign TASK-001 maria β ...assign-maria.md
After a rebase, both event files end up side by side; last-writer-wins is resolved by timestamp β no merge conflict.