feat(rpc): expose Docusaurus DocSite methods over OpenRPC #108

Merged
rawdaGastan merged 7 commits from development_docs_rpc_methods into development 2026-04-27 09:58:55 +00:00
Member

Summary

Roll out the six missing Docusaurus DocSite capabilities tracked in #101 over JSON-RPC. Each child issue lands as its own focused commit on this branch; the PR body's checklist below tracks progress. The PR is mergeable into development once all six are ticked.

This iteration ships the first method: docs.installTemplate.

Closes #101 once all child issues are checked.

  • Closes #102docs.installTemplate

Child issue progress

  • #102docs.installTemplate
  • #103docs.updateTemplate
  • #104docs.build
  • #105docs.dev (long-running)
  • #106docs.publish
  • #107docs.publishDev

Changes in this iteration (#102)

  • src/bin/hero_docs.rs — new install-template subcommand calling hero_books_docusaurus::template::install_template(&path, reset) directly.
  • crates/hero_books_server/src/web/rpc.rs
    • handle_docs_install_template handler (validation -32602, dedup key docs_install_template_<input_hash>).
    • Dispatch arm "docs.installTemplate" between docs.generate and docs.jobStatus.
    • handle_docs_job_status documents that docs_install_template_* jobs intentionally do not synthesise an output_path (path not recoverable from input hash).
    • New ## Docs section in the file-level doc-comment header listing all four docs.* methods.
    • New unit test test_docs_install_template_missing_params.
  • crates/hero_books_server/src/web/rpc_spec.rs — inline schema (used by rpc.discover) updated.
  • crates/hero_books_server/openrpc.json — new method entry; info.version bumped 0.1.5 -> 0.1.6.
  • crates/hero_books_server/openrpc.client.generated.rs — auto-regenerated by the openrpc_client! macro.

Test Results (this iteration)

  • cargo check -p hero_books_server — OK
  • cargo check --bin hero_docs — OK
  • cargo test -p hero_books_server --lib — 17 passed, 0 failed (incl. new test_docs_install_template_missing_params)
  • INSTRUCTIONS_OPENRPC.md §Verification spec/impl-parity diff — empty (clean)
  • Live RPC test against running hero_books_server/hero_proc: discovery, validation, submission, idempotent dedup, hero_proc dispatch, docs.jobStatus error-tail surfacing — all confirmed.

How to validate locally

# Build & install via supervisor
make run

# Discover should list docs.installTemplate with required `path` + optional `reset`
curl -s --unix-socket ~/hero/var/sockets/hero_books/rpc.sock \
  -X POST http://localhost/rpc \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","method":"rpc.discover","id":1}' \
  | jq '.result.methods[] | select(.name=="docs.installTemplate")'

# Submit
curl -s --unix-socket ~/hero/var/sockets/hero_books/rpc.sock \
  -X POST http://localhost/rpc \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","method":"docs.installTemplate","params":{"path":"/tmp/test_install_rpc"},"id":2}'
# -> {"jsonrpc":"2.0","result":{"job_id":"<n>"},"id":2}

# Poll
curl -s --unix-socket ~/hero/var/sockets/hero_books/rpc.sock \
  -X POST http://localhost/rpc \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","method":"docs.jobStatus","params":{"job_id":"<n>"},"id":3}'

Notes

  • The bun runtime must be installed for template::install_template to complete successfully — same prerequisite as docs.new / docs.generate. Not a defect introduced by this PR.
## Summary Roll out the six missing Docusaurus `DocSite` capabilities tracked in #101 over JSON-RPC. Each child issue lands as its own focused commit on this branch; the PR body's checklist below tracks progress. The PR is mergeable into `development` once all six are ticked. This iteration ships the first method: `docs.installTemplate`. ## Related Issues Closes #101 once all child issues are checked. - Closes #102 — `docs.installTemplate` ## Child issue progress - [x] #102 — `docs.installTemplate` - [x] #103 — `docs.updateTemplate` - [x] #104 — `docs.build` - [x] #105 — `docs.dev` (long-running) - [x] #106 — `docs.publish` - [x] #107 — `docs.publishDev` ## Changes in this iteration (#102) - `src/bin/hero_docs.rs` — new `install-template` subcommand calling `hero_books_docusaurus::template::install_template(&path, reset)` directly. - `crates/hero_books_server/src/web/rpc.rs` - `handle_docs_install_template` handler (validation `-32602`, dedup key `docs_install_template_<input_hash>`). - Dispatch arm `"docs.installTemplate"` between `docs.generate` and `docs.jobStatus`. - `handle_docs_job_status` documents that `docs_install_template_*` jobs intentionally do not synthesise an `output_path` (path not recoverable from input hash). - New `## Docs` section in the file-level doc-comment header listing all four `docs.*` methods. - New unit test `test_docs_install_template_missing_params`. - `crates/hero_books_server/src/web/rpc_spec.rs` — inline schema (used by `rpc.discover`) updated. - `crates/hero_books_server/openrpc.json` — new method entry; `info.version` bumped `0.1.5 -> 0.1.6`. - `crates/hero_books_server/openrpc.client.generated.rs` — auto-regenerated by the `openrpc_client!` macro. ## Test Results (this iteration) - `cargo check -p hero_books_server` — OK - `cargo check --bin hero_docs` — OK - `cargo test -p hero_books_server --lib` — 17 passed, 0 failed (incl. new `test_docs_install_template_missing_params`) - INSTRUCTIONS_OPENRPC.md §Verification spec/impl-parity diff — empty (clean) - Live RPC test against running `hero_books_server`/`hero_proc`: discovery, validation, submission, idempotent dedup, hero_proc dispatch, `docs.jobStatus` error-tail surfacing — all confirmed. ## How to validate locally ```sh # Build & install via supervisor make run # Discover should list docs.installTemplate with required `path` + optional `reset` curl -s --unix-socket ~/hero/var/sockets/hero_books/rpc.sock \ -X POST http://localhost/rpc \ -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","method":"rpc.discover","id":1}' \ | jq '.result.methods[] | select(.name=="docs.installTemplate")' # Submit curl -s --unix-socket ~/hero/var/sockets/hero_books/rpc.sock \ -X POST http://localhost/rpc \ -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","method":"docs.installTemplate","params":{"path":"/tmp/test_install_rpc"},"id":2}' # -> {"jsonrpc":"2.0","result":{"job_id":"<n>"},"id":2} # Poll curl -s --unix-socket ~/hero/var/sockets/hero_books/rpc.sock \ -X POST http://localhost/rpc \ -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","method":"docs.jobStatus","params":{"job_id":"<n>"},"id":3}' ``` ## Notes - The `bun` runtime must be installed for `template::install_template` to complete successfully — same prerequisite as `docs.new` / `docs.generate`. Not a defect introduced by this PR.
feat(rpc): expose docs.installTemplate over OpenRPC
All checks were successful
Test / test (pull_request) Successful in 7m43s
Test / integration (pull_request) Successful in 4m58s
1dc8a77bfa
Wire DocSite::install_template through the JSON-RPC layer following the
existing docs.new / docs.generate pattern: the handler submits a hero_proc
job that shells out to a new `hero_docs install-template` subcommand, and
returns a job_id for clients to poll via docs.jobStatus.

handle_docs_job_status's prefix-strip block intentionally does not produce
an output_path for docs_install_template_* jobs — the user-supplied path
is not recoverable from the input hash. The same approach will apply to
the upcoming #103-#107 methods.

Bumps openrpc.json info.version 0.1.5 -> 0.1.6.

#102
feat(rpc): expose docs.updateTemplate over OpenRPC
Some checks failed
Test / test (pull_request) Successful in 6m29s
Test / integration (pull_request) Has been cancelled
cd3cc9bb6a
Wire DocSite::update_template through the JSON-RPC layer following the
same pattern as docs.installTemplate (#102): the handler submits a
hero_proc job that shells out to a new `hero_docs update-template`
subcommand and returns a job_id for clients to poll via docs.jobStatus.

Path semantics are identical to docs.installTemplate — `path` is the
Docusaurus build directory, passed straight to
template::update_template(&Path), no heroscript loading.

handle_docs_job_status's prefix-recognition comment now lists
docs.updateTemplate alongside docs.installTemplate; no behaviour change
since neither prefix matches the strip-list.

info.version unchanged at 0.1.6 — single version bump per rolling PR.

#103
feat(rpc): expose docs.build over OpenRPC with output_path recovery
All checks were successful
Test / test (pull_request) Successful in 6m28s
Test / integration (pull_request) Successful in 5m18s
86b7f44f48
Wire DocSite::build through the JSON-RPC layer. Unlike docs.installTemplate
and docs.updateTemplate (#102, #103) which use hashed action names and
produce no output_path, docs.build encodes the user-supplied build path
directly into the hero_proc action name with URL-safe base64 (no padding):

    action_id = docs_build_<base64url_no_pad(path)>

This preserves dedup (same path -> same encoded name) while making the
path recoverable on status polls. handle_docs_job_status now strips the
docs_build_ prefix and base64-decodes the suffix to surface
output_path = <path>/build for completed jobs.

The path-recovery logic is factored out of handle_docs_job_status's
closure into a pure helper derive_docs_output_path(action_name, cache_dir)
covering three buckets: docs_new_*/docs_generate_* -> <cache>/<hash>/build;
docs_build_* -> <decoded_path>/build; everything else -> None.

Decoder fails closed: malformed base64 or non-UTF-8 bytes return None
rather than emitting a bogus output_path.

info.version unchanged at 0.1.6 - single bump per rolling PR.

#104
feat(rpc): expose docs.dev (long-running) over OpenRPC
All checks were successful
Test / test (pull_request) Successful in 7m38s
Test / integration (pull_request) Successful in 4m3s
5a4e9bbb1d
Wire DocSite::dev(host, port) through the JSON-RPC layer as a
long-running hero_proc job. The dev server runs without a timeout cap
until the caller cancels it via hero_proc's job.cancel JSON-RPC with
the returned job_id (there is no separate docs.devStop, per the issue
body and INSTRUCTIONS_OPENRPC.md).

Backwards-compatible helper refactor: submit_or_dedup_docs_job keeps
its original 4-arg signature as a thin wrapper that calls a new
sibling submit_or_dedup_docs_job_with_timeout(..., timeout_ms:
Option<i64>). Existing five callers don't change. handle_docs_dev calls
the new variant with None (= no timeout, per hero_proc SDK convention
"0 = no timeout").

Action name: docs_dev_<input_hash> where the hash includes path, host,
and port so two dev sessions on different ports get distinct job_ids.

handle_docs_job_status returns no output_path for docs_dev_* (output is
a live HTTP server, not a build directory). The existing docs_*
prefix-recognition test from #104 already covers this.

info.version unchanged at 0.1.6 - single bump per rolling PR.

#105
feat(rpc): expose docs.publish over OpenRPC
All checks were successful
Test / test (pull_request) Successful in 7m28s
Test / integration (pull_request) Successful in 4m11s
d8a174a046
Wire build::publish through the JSON-RPC layer as docs.publish. The
handler shells out to a new `hero_docs publish` subcommand which calls
build::publish(&path, &[], &name) directly -- empty destinations slice
triggers the default PublishDest (production rsync host) using the
supplied `name` as the site_name. The rsync password is read from the
RSYNCD_SECRET env var on the server side.

Path semantics are consistent with #102-#105: `path` is a Docusaurus
build directory, not a heroscript path. heroscript-aware destinations
are out of scope for this PR.

Action name: docs_publish_<input_hash> where the hash includes both
path and name. derive_docs_output_path returns None for docs_publish_*
(locked by extending the existing prefix-recognition test).

info.version unchanged at 0.1.6 - single bump per rolling PR.

#106
feat(rpc): expose docs.publishDev over OpenRPC
All checks were successful
Test / test (pull_request) Successful in 6m39s
Test / integration (pull_request) Successful in 6m0s
85cf3fa0c7
Wire DocSite::publish_dev() through the JSON-RPC layer. Unlike
docs.publish (#106) which uses a build-directory path with the default
production rsync target, docs.publishDev takes a heroscript path/URL
and uses the dev destinations defined per-site via the heroscript's
!!site.publish_dev directive (parsed by parse_publish(_, _, true) in
hero_books_docusaurus::heroscript).

The path-semantics divergence reflects that production publish has a
sensible global fallback while dev publish needs per-site config (the
codebase has no global default dev destination). The hero_docs
publish-dev runner loads DocSite::from_heroscript(&path), overrides
docsite.name = name, and calls docsite.publish_dev() which rsyncs to
build_dest_dev. If the heroscript has no !!site.publish_dev directive,
falls back to a single default destination using `name` as site_name.

Action name: docs_publish_dev_<input_hash>; no output_path (remote
rsync push, not a local directory).

Bumped the crate's macro recursion_limit to 256 — adding
docs.publishDev to the inline get_openrpc_schema json! block exceeds
the default 128. Build-time only; no runtime effect.

This is the final child of the rolling PR for #101 (6 of 6).

info.version unchanged at 0.1.6 - single bump per rolling PR.

#107
chore(docs): remove INSTRUCTIONS_OPENRPC.md
All checks were successful
Test / test (pull_request) Successful in 8m21s
Test / integration (pull_request) Successful in 4m2s
16c451f521
Superseded by PR #108. The file was a planning artefact describing the
work to expose the six missing DocSite methods over OpenRPC; with
#102-#107 all shipped, every "to do" in the doc is done. The
spec/impl-parity verification snippet survives in the PR's commit
messages and the per-method test results posted on each child issue.

#101
rawdaGastan merged commit 3f6dfdeb2f into development 2026-04-27 09:58:55 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_books!108
No description provided.