hero_slides_server: implement 15 undispatched OpenRPC methods (deckjobs.*, wizard.*, slide.setLink/clearLink/setImageModel/getStaleness/revertToLastGenerated/resolveContext, bg.extractTheme, deck.staleness, folder.pick) #51
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Surfaced by hero_slides#49's schema audit (
scripts/smoke_openrpc.py) — 15 methods are advertised incrates/hero_slides_server/openrpc.jsonand called by the JS dashboard, but have nomatcharm incrates/hero_slides_server/src/rpc.rs. Same silent-failure class as thecollection.*gap PR #48 closed: each call returns-32000 "Method not found", the JS swallows it intry{…}catch{toast(…)}, and the operator only sees the side-effect (button does nothing).The 15 methods
Slide Wizard (4) — flagship feature on the Home page CTA
wizard.runAsync— kick off async wizard run (params:{collection, deck, mode, intent, ...})wizard.runJobStatus— poll status (params:{key})wizard.runJobLogs— stream logs (params:{key, lines?})wizard.runResult— read final result (params:{output_file, input_file?})Per-deck job tracking (5) — Slides tab "Jobs" sidebar
deckjobs.list(params:{collection, deck})deckjobs.status(params:{job_id})deckjobs.logs(params:{job_id, lines?})deckjobs.cancel(params:{job_id})deckjobs.result(params:{job_id})Slide linking + per-slide config (6)
slide.setLink— link two slides (params:{collection, deck, slide, src_collection, src_deck, src_slide_slug})slide.clearLink(params:{collection, deck, slide})slide.setImageModel— per-slide model override (params:{collection, deck, slide, model?})slide.getStaleness(params:{deck_path, slide_name})slide.revertToLastGenerated(params:{deck_path, slide_name})slide.resolveContext(params:{collection, deck, slide, context_selection?})Misc (3)
bg.extractTheme— derive a theme from a background image (params:{collection, deck, folder?, file?, data?, mime_type?})deck.staleness(params:{path})folder.pick— UI affordance for picking a filesystem folder (no params)Acceptance
match req.method.as_str()incrates/hero_slides_server/src/rpc.rs.hero_slides_libwhere the lib already has the function (e.g.deck.stalenesslikely just needs to call an existing staleness helper).JobManagerasync-job pattern (seedeck.generateAsyncfor the template).scripts/smoke_openrpc.pypost-fix: METHOD_MISSING count drops from 15 to 0.slide.setImageModel.Design notes
{deck_path, slide_name}legacy params (e.g.slide.getStaleness,slide.revertToLastGenerated). Thelegacy_param_shim(PR #50) auto-translates{collection, deck, slide}→ these legacy keys, so new handlers can either accept either shape or use the helpersparam_deck_path/param_slidedirectly.folder.pickis a UI affordance — server may want to return a curated set of allowed roots (e.g.~/hero/var/hero_slides/,~/Documents) rather than expose a raw filesystem picker.Refs
Closing — bucket A + B verified end-to-end. Bucket C lives in #54.
Buckets shipped
wizard.runAsync,wizard.runJobStatus,wizard.runJobLogs,wizard.runResult,deckjobs.list,deckjobs.status,deckjobs.logs,deckjobs.cancel,deckjobs.result1c4391eslide.setImageModel,slide.revertToLastGenerated,slide.resolveContext,bg.extractThemec897938slide.setLink,slide.clearLink,slide.getStaleness,deck.staleness,folder.pickNote: bucket A turned out to be pure dispatch glue — every handler already existed in the codebase (wizard.* in
generate_job.rs:1127/1590/1602/1693, deckjobs.* injobs/rpc.rs:46/68/75/86/102) but nomatcharm pointed at them. Thejobs/mod.rscomment literally said the re-exports "become load-bearing when RPC handlers are wired in A.5 / A.6" — bucket A wired them.Bucket B added 4 new handler functions (~150 LOC) wrapping existing lib helpers (
slide_set_image_model, theslide_list_versions+slide_restore_version+slide_get_contentcomposition for revert,resolve_context,extract_theme_from_image/extract_theme_from_pdf).Verification (2026-05-10, live workstation)
Deployed the bucket-B binary to
~/hero/bin/hero_slides_serverand drove the dashboard athttp://127.0.0.1:9988/hero_slides/admin/via Hero Browser MCP. Every one of the 13 newly-dispatched methods reached a real handler — zero -32601 / "Method not found" in the response set:wizard.runJobStatus/Logs/Resultdeckjobs.listJobSnapshot[]deckjobs.status/logs/cancel/result"unknown job id"for the bogus id (proves JobManager dispatch)slide.setImageModel({…model: ''}){ok: true}— actually cleared the per-slide overrideslide.resolveContext({…}){entries: [], fingerprint: "e3b0c4..."}— resolver ranslide.revertToLastGenerated({…}){content: "# Write in markdown..."}— restored snapshotbg.extractTheme({…})Dashboard loaded clean, console:
[](zero messages).Smoke harness delta
scripts/smoke_openrpc.pyMETHOD_MISSING: 15 → 5 (only bucket C left, all tracked in #54).Sister issues closed in the same arc
Signed-off-by: mik-tf