Thanks for considering it. IntelNav is two binaries
(intelnav chat client + intelnav-node host daemon) sharing one
substantial library (crates/app) on top of a small set of leaf
crates. Read docs/architecture.md before
your first non-trivial change — the workspace dependency diagram +
runtime sequence diagram there are the fastest way in.
git clone git@github.com:IntelNav/intelnav.git
cd intelnav
bash scripts/provision.sh # system deps + rust + workspace check
bash scripts/install-libllama.sh # fetch a prebuilt libllama into the cacheprovision.sh supports Debian/Ubuntu, Fedora, Arch, macOS. For other
platforms install build-essential, pkg-config, libssl-dev, and
the Rust toolchain manually.
install-libllama.sh auto-detects your GPU vendor and pulls the
matching prebuilt tarball from the latest
IntelNav/llama.cpp release
into ~/.cache/intelnav/libllama/bin. The runtime auto-discovers it
on startup; you don't need to set INTELNAV_LIBLLAMA_DIR by hand.
MSRV: Rust 1.88. The repo's rust-toolchain.toml pins
channel = "stable", so rustup users pick up a compatible version
automatically.
# fast check before every commit
cargo check --workspace --all-targets
# full test suite
cargo test --workspace --no-fail-fast
# format + lint
cargo fmt --all
cargo clippy --workspace --all-targets -- -D warningsjust check / just test / just fmt / just lint are aliases.
#![forbid(unsafe_code)]in every crate exceptintelnav-cli, which drops tolibc::dup2for the TUI's stderr redirect (marked#[allow(unsafe_code)]inline). Don't introduceunsafeelsewhere without explicit justification.corehas no heavy deps. Shape-only types. Keep it that way.runtimeis the only crate that depends onggml/libllama.wire,crypto,net,corestay inference-backend agnostic.- Protocol messages are additive. If you add a field to a
Msgvariant, use#[serde(default, skip_serializing_if = "Option::is_none")]so proto-v1 peers still decode. - Layer-split must stay bit-identical. Any change to the
layer-range forward path must keep
cargo test -p intelnav-ggml --test bit_identicalpassing (thefive_scenarios_bit_identicalrunner: max_abs_diff == 0 vs the full-model forward on q4_k_m, across embed-only, head-only, middle-slice, etc.).
- Crates use
tracing— neverprintln!/eprintln!for non-CLI output. - The CLI routes logs to
$XDG_STATE_HOME/intelnav/intelnav.logwhen the TUI is active (otherwise stderr). Don't bypass this — native deps that write raw FD 2 will paint over the Ratatui canvas. - Log level:
-v= debug,-vv= trace.
- Create a new commit per logical change. Don't amend merged commits.
- Never push
--forcetomain. Never skip hooks (--no-verify). - Don't commit build artifacts (
target/,*.aux,*.log). Cargo.lockis committed (binary workspace).
- The wire protocol is normative. Changes to
Msgmust updatespecs/protocol-v1.md. - The threat model is normative. Security-relevant changes must
update
specs/security-v1.md.
cargo new --lib crates/<name>.- Add to
members = [...]in the rootCargo.toml. - Add a workspace-level path dep
(
intelnav-<name> = { path = "crates/<name>" }). - Write a one-paragraph
crates/<name>/README.mdfollowing the pattern in the existing crates. - Add
#![forbid(unsafe_code)]unless you have a reason not to.
The fastest way to exercise an end-to-end change:
cargo build --release -p intelnav-cli -p intelnav-node
INTELNAV_RELAY_ONLY=1 ./target/release/intelnavInside the TUI: /help lists slash commands, /keybindings lists
the key shortcuts, /doctor runs preflight inline. Logs go to
~/.local/state/intelnav/intelnav.log while the TUI is up.
For non-interactive smoke (no Ratatui):
echo "say hello" | ./target/release/intelnav --mode local ask \
--model qwen2.5-0.5b-instruct-q4_k_mIf you need to drive the daemon's control RPC by hand:
echo '{"method":"status"}' \
| nc -U ~/.local/share/intelnav/control.sock -w 1