feat: CLI quick wins — heph-tui --version, fuzzy --project, heph context, version RPC #6

Merged
eblume merged 6 commits from feature/cli-quick-wins into main 2026-06-04 12:42:20 -07:00

6 commits

Author SHA1 Message Date
7f48a2a1c5 infra: add cargo-fmt-check pre-push prek hook (mirror CI)
All checks were successful
Build / validate (pull_request) Successful in 5m25s
The cargo-fmt failure on this PR slipped to CI because the pre-commit
prek hooks were never installed in the working clone. The existing
cargo-fmt hook reformats in place but only when it runs. Add a
pre-push cargo-fmt-check hook (`cargo fmt --all --check`) that mirrors
CI's Dagger `check` step exactly, so an unformatted commit is blocked
locally before it can reach the runner — even if the pre-commit hook was
skipped or not installed. Filtered to .rs pushes so Rust-free pushes pay
nothing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 12:36:12 -07:00
8d80208726 style: rustfmt the new rpc_socket tests
Some checks failed
Build / validate (pull_request) Has been cancelled
The project.resolve socket test had a node.create call over rustfmt's
line limit; CI's `cargo fmt --all --check` flagged it. Wrap it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 12:31:01 -07:00
7914232ec4 feat: add a version RPC returning the daemon build version
Some checks failed
Build / validate (pull_request) Failing after 15s
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) <noreply@anthropic.com>
2026-06-04 11:13:47 -07:00
babdb21c0a feat: heph context <task-id> reads/edits a task's context doc by id
Editing a task's canonical-context doc body previously meant looking up
its `canonical_context_id` (e.g. via `heph list --json`) and then
`heph node update <doc-id> --body`. Add a `heph context <task-id>`
command that resolves the canonical-context doc from the task's outgoing
links and:

  * prints the body with no flag,
  * `--body <text>` replaces it (`-` reads stdin, matching `node update`),
  * `--append <text>` adds a blank-line-separated paragraph.

Errors clearly when the id has no canonical-context doc (e.g. a plain
doc node rather than a task). Purely a client-side CLI convenience — no
new RPC.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 11:09:53 -07:00
fc25f6ac51 feat: --project arg is case-insensitive / prefix-fuzzy when unambiguous
The `--project <name>` argument matched titles case-sensitively and
exactly, so `--project hephaestus` or `--project heph` failed against a
`Hephaestus` project. Make project-name resolution forgiving but
deterministic, via a tiered match in `resolve_project_id`:

  1. exact (case-sensitive) — the historical behavior; always wins
  2. case-insensitive exact — only when unambiguous
  3. case-insensitive prefix — only when unambiguous

Ambiguous fuzzy matches resolve to None (callers report "no project
named X") rather than silently picking one. This single resolver already
backed `heph list --project` (via project_scope); route the CLI's
task/edit/promote/parent path through it too with a new `project.resolve`
RPC + `Store::resolve_project`, so every `--project` surface behaves the
same.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 10:57:37 -07:00
58a5544d44 feat: heph-tui --version reports version + build SHA
heph-tui was the one daily-driver binary that did not answer --version.
Add the same clap `version = heph_core::VERSION` attribute that heph and
hephd already carry, so all three report `X.Y.Z (sha)` consistently.

Addresses the heph-tui half of the cross-binary --version task.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 10:52:52 -07:00