CLI tool berbasis C++ yang menerapkan Retrieval-Augmented Generation (RAG)
untuk menjawab pertanyaan seputar isi file konfigurasi Hyprland (window
manager Linux berbasis Wayland), dengan jawaban yang wajib bersitasi ke
path:line sumber aslinya di config kamu.
Prinsip inti: read-only (tidak pernah mengedit config), jawaban HANYA berdasarkan isi config yang beneran ada (bukan pengetahuan umum LLM), dan setiap klaim harus bisa ditelusuri balik ke baris config yang tepat.
Pengguna Hyprland yang konfigurasinya kompleks (banyak file, saling
source, ratusan baris) sering kesulitan mencari pengaturan tertentu tanpa
hafal struktur filenya. hyprask memungkinkan tanya pakai bahasa natural
("gimana cara buka terminal?") dan dapat jawaban akurat lengkap dengan
sitasi presisi, tanpa perlu grep manual.
Fase indexing (dijalankan sekali/berkala, offline):
hyprland.conf --[parser]--> chunk --[embedding API]--> vector --[simpan]--> vector store
Fase query (tiap kali kamu tanya):
pertanyaan --[embed]--> vector --[cari mirip]--> top-k chunk --[+ LLM]--> jawaban bersitasi
- CMake >= 3.16
- Compiler C++17 (g++/clang++)
- libcurl (dev headers):
sudo apt install libcurl4-openssl-dev
Semua dependency lain (toml++, nlohmann/json) sudah di-vendor di
third_party/, tidak perlu package manager tambahan.
mkdir build && cd build
cmake ..
cmake --build .Binary hypraskcpp akan ada di folder build/. Nama binary bisa
di-custom tanpa edit source:
cmake -DHYPRASK_APP_NAME='"namabaru"' ..hypraskcpp initWizard bakal nanya lokasi hyprland.conf, provider embedding & LLM
(base_url, model, nama env var API key), lalu otomatis nawarin lanjut
parse dan index.
Sebelum jalanin, set API key sesuai yang diminta wizard:
export HYPRASK_EMBEDDING_API_KEY="sk-..."
export HYPRASK_LLM_API_KEY="sk-..."Support provider apapun yang OpenAI-compatible — termasuk model lokal
kayak Ollama (base_url = "http://localhost:11434/v1"), tanpa perlu ubah
kode sama sekali.
hypraskcpp ask "gimana cara buka terminal?"
hypraskcpp ask "berapa top-k yang dipakai?" --no-llm # cuma print hasil retrieval, skip LLMhypraskcpp chat --session harianRetrieval "sadar konteks" (gabung 1-2 pertanyaan terakhir + pertanyaan
baru jadi query pencarian), replay histori lengkap kalau resume session
lama, label warna beda buat You:/Assistant:.
hypraskcpp history # list semua session tersimpan
hypraskcpp history --session harian # lihat isi 1 session (read-only)hypraskcpp statusNgecek: config.toml valid, hyprland.conf bisa dibaca, API key ke-set, host embedding/LLM bisa dijangkau (HTTP CONNECT-ONLY, bukan ICMP — tanpa kena biaya API), chunks/vectors ada, staleness index vs config terbaru, jumlah session tersimpan.
hypraskcpp eval dataset.json
hypraskcpp eval dataset.json --k 5 # override top_k, sekali pakai doangBaca dataset Q&A ground-truth, hitung Hit Rate dan MRR (Mean
Reciprocal Rank). Matching-nya range-aware: cocok kalau baris yang
di-expected ada di dalam rentang [line, endLine] hasil retrieval —
jadi 1 dataset yang sama valid dipakai baik strategi line maupun
block.
Format dataset:
[
{ "question": "gimana cara buka terminal?", "expected": ["UserKeybinds.conf:23"] },
{ "question": "berapa resolusi monitor utama?", "expected": ["monitors.conf:3"] }
]hypraskcpp parser # lihat strategi aktif
hypraskcpp parser change # toggle line <-> block, tersimpan ke config.tomlline— 1 baris config = 1 chunk, sitasi presisi 1 barisblock— baris dalam{ }digabung jadi 1 chunk (konteks nested ikut kebawa, misaldecoration { shadow {...} blur {...} }jadi 1 kesatuan), sitasi jadi rentang baris
Dua strategi hidup bersamaan di disk (chunks_line.json /
chunks_block.json, vectors_line.json / vectors_block.json), tidak
saling timpa. ask/chat/eval otomatis pakai file sesuai strategi
yang lagi aktif.
~/.config/hypraskcpp/config.toml:
[paths]
hyprland_conf = "~/.config/hypr/hyprland.conf"
[embedding]
provider = "openai"
model = "text-embedding-3-small"
base_url = "https://api.openai.com/v1"
api_key_env = "HYPRASK_EMBEDDING_API_KEY"
[llm]
provider = "openai"
model = "gpt-4o-mini"
base_url = "https://api.openai.com/v1"
api_key_env = "HYPRASK_LLM_API_KEY"
[retriever]
top_k = 8
[chat]
history_turns = 5
[parser]
strategy = "line"Semua field punya default kalau tidak diisi — config.toml boleh parsial.
web/tree_viewer.html — buka isi index dalam bentuk visual:
cd ~/.local/share/hypraskcpp
python3 -m http.server 8000
# buka http://localhost:8000/tree_viewer.html- Auto-detect
chunks_line.json/chunks_block.json, tab switcher kalau dua-duanya ada - Mode List (tree berdasar source chain, expand/collapse per node atau semua sekaligus)
- Mode True AST — diagram visual dengan pan/zoom, parse
key = valuejadi node nested per argumen, sub-blok (shadow {},blur {}) jadi node terpisah yang bisa dibuka-tutup sendiri
Catatan: ini tree berdasarkan source chain (file mana nge-
sourcefile mana) dan struktur blok{ }, bukan AST grammar penuh dari bahasa config Hyprland.
include/
├── config/ app_identity, xdg_paths, config (baca/tulis TOML), config_wizard
├── parser/ source-chain resolver + chunker (strategi line & block)
├── embedding/ HTTP client ke endpoint /embeddings (OpenAI-compatible)
├── indexer/ orkestrasi batch -> embed -> simpan
├── store/ vector store: brute-force cosine similarity, JSON manual
├── retriever/ embed pertanyaan + panggil topK()
├── llm/ HTTP client ke endpoint /chat/completions
├── answer/ build_prompt (SYSTEM_PROMPT + Context + Question), render (CLI box UI)
├── chat/ REPL interaktif + histori
├── session/ simpan/baca histori percakapan (JSON per nama session)
├── status/ cek kesehatan setup
├── eval/ evaluasi retrieval otomatis (Hit Rate, MRR)
third_party/ toml++, nlohmann/json (vendored)
web/ tree_viewer.html
- Vector store: JSON manual + brute-force cosine similarity, bukan
SQLite/ChromaDB — cukup buat skala ratusan chunk, exact search (bukan
approximate), tanpa dependency tambahan. Titik upgrade cuma di 1
fungsi (
topK()) kalau suatu saat perlu ganti ke ANN library. - Embedding dense/semantic, bukan BM25/TF-IDF murni — user nanya pakai bahasa natural yang sering beda kata literal dari isi config (misal "terminal" vs "kitty" di config).
- Provider-agnostic —
base_urlbebas dikonfigurasi, jadi jalan ke cloud API atau model lokal tanpa ubah kode.
- Evaluasi baru mengukur kualitas retrieval (Hit Rate, MRR), belum ada pengukuran kualitas generation (faithfulness/halusinasi jawaban LLM).
- Belum ada hybrid search (embedding + keyword/BM25).
top_kdefault (8) belum dioptimasi lewat eksperimen sistematis.- Read-only murni — tidak ada fitur edit config dari dalam app.
Project belajar C++ sekaligus draft riset RAG diterapkan ke domain file konfigurasi sistem (belum banyak diteliti dibanding domain dokumen naratif seperti PDF/artikel ilmiah).