From 7914232ec47b8a2dc74483a8bd59809652eb7ee2 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Thu, 4 Jun 2026 11:13:47 -0700 Subject: [PATCH] feat: add a `version` RPC returning the daemon build version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RPC clients (the hephaestus.nvim plugin, for its `:Heph version` command) had no way to learn which hephd they are talking to — `health` returns counts, not a version. Add a tiny `version` method returning `{ version: heph_core::VERSION }`, the same `X.Y.Z (sha)` string the binaries print for --version. No store access needed. Co-Authored-By: Claude Opus 4.8 (1M context) --- crates/hephd/src/rpc.rs | 1 + crates/hephd/tests/rpc_socket.rs | 31 +++++++++++++++++++++++++ docs/changelog.d/version-rpc.feature.md | 1 + 3 files changed, 33 insertions(+) create mode 100644 docs/changelog.d/version-rpc.feature.md diff --git a/crates/hephd/src/rpc.rs b/crates/hephd/src/rpc.rs index 5a46cd8..bc29eca 100644 --- a/crates/hephd/src/rpc.rs +++ b/crates/hephd/src/rpc.rs @@ -417,6 +417,7 @@ pub fn dispatch(store: &mut dyn Store, method: &str, params: Value) -> Result json!({ "version": heph_core::VERSION }), "health" => json!(store.health()?), "search" => { let p: SearchParams = parse(params)?; diff --git a/crates/hephd/tests/rpc_socket.rs b/crates/hephd/tests/rpc_socket.rs index 9debf4a..a9a2ba1 100644 --- a/crates/hephd/tests/rpc_socket.rs +++ b/crates/hephd/tests/rpc_socket.rs @@ -109,6 +109,37 @@ fn node_resolve_is_exact_not_fuzzy_over_socket() { assert_eq!(missing, Value::Null); } +#[test] +fn version_rpc_returns_build_version() { + let (socket, _dir) = spawn_daemon(); + let mut c = client(&socket); + + let got = c.call("version", json!({})).unwrap(); + assert_eq!(got["version"], heph_core::VERSION); +} + +#[test] +fn project_resolve_is_case_insensitive_and_prefix_fuzzy_over_socket() { + let (socket, _dir) = spawn_daemon(); + let mut c = client(&socket); + + let proj = c + .call("node.create", json!({ "kind": "project", "title": "Hephaestus" })) + .unwrap(); + let pid = proj["id"].as_str().unwrap().to_string(); + + // Case-insensitive exact and unambiguous prefix both resolve to the project. + for name in ["Hephaestus", "hephaestus", "heph"] { + let got = c.call("project.resolve", json!({ "name": name })).unwrap(); + assert_eq!(got["id"], pid, "resolving {name:?}"); + } + // An unknown name is JSON null, not an error. + let missing = c + .call("project.resolve", json!({ "name": "nope" })) + .unwrap(); + assert_eq!(missing, Value::Null); +} + #[test] fn task_create_appears_in_next_with_context_link() { let (socket, _dir) = spawn_daemon(); diff --git a/docs/changelog.d/version-rpc.feature.md b/docs/changelog.d/version-rpc.feature.md new file mode 100644 index 0000000..36171fd --- /dev/null +++ b/docs/changelog.d/version-rpc.feature.md @@ -0,0 +1 @@ +New `version` RPC returns the daemon's build version (`heph_core::VERSION`, e.g. `1.0.0 (ab6701d12)`), so RPC clients — notably the `hephaestus.nvim` plugin's `:Heph version` command — can report which `hephd` they are talking to without shelling out to the binary.