feat(library): expose the library over the API

POST /api/library/runs harvests now; GET /api/library/items lists what
the library holds. Thin wrappers — the work stays in crate::library — so
a run can be started by a person, a schedule or the UI rather than only
from an integration test.

The response reports `healthy` explicitly rather than leaving a caller to
infer it from an empty `shelved` list. A quiet week and a broken run both
shelve zero papers, and collapsing those two is the exact ambiguity that
cost most of this week.

Failure reasons go to the log, not the response body: they can carry the
remote URL and raw git stderr.

AppState gains an optional blob store (the shelf), wired from the server
binary where storage is already constructed. Optional because AppState::new
is used by tests that never touch blobs; a route that needs it fails
loudly rather than the constructor demanding it everywhere.

393 tests, clippy clean.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
Omar Sobh
2026-08-03 10:21:00 -07:00
co-authored by Claude Opus 5
parent 09c6496725
commit 107f0dbced
4 changed files with 168 additions and 1 deletions
+1
View File
@@ -13,6 +13,7 @@ pub mod gateway;
pub mod health;
pub mod identity;
pub mod level_up;
pub mod library;
pub mod missions;
pub mod nodes;
pub mod oauth;