No description
  • Rust 98.4%
  • Makefile 1.1%
  • Shell 0.5%
Find a file
mik-tf 9036d1712b chore(hero_office): D-10 sweep — service.toml + herolib_core::base on 3 binaries + cargo update absorb + dep audit
Workspace canonical-base migration on all 3 binary crates (CLI + server + admin) — none of them
had service.toml on disk pre-sweep (s102/s104-shape wholesale), with the post-b814ec07
service_base!() macro providing both SERVICE_TOML and BUILD_NR constants.

D-10 acceptance (5/5):
1. Branch is literal `development_mik` (per feedback_branch_name_development_mik).
2. `cargo update` absorbed the 4-pin cascade — hero_lib b814ec07 (BUILD_NR macro extension),
   hero_proc_sdk 7fcea44 (socket/SSE helpers + service.toml metadata cleanup), hero_rpc f17dcd71,
   hero_proxy 8bd8ad5. Cascade clean — no Run-API drift to absorb (hero_office uses
   hero_proc_factory().restart_service() directly, no job_create / run_create).
3. `lab infocheck`: 3 crate(s) clean, 0 finding(s) total. All 3 binaries pass --info ok via
   handle_info_flag(SERVICE_TOML) from herolib_core::base.
4. Conservative dep audit per crate (grep src/+tests/+benches/+build.rs, zero-match strip):
   - hero_office_server:   strip async-trait, clap, thiserror, tower-service
   - hero_office_admin:    strip async-trait, http-body-util, mime_guess, tower-service
   - hero_office_sdk:      strip anyhow, thiserror, tokio, tracing
   - hero_office_examples: strip serde_json
   Total 13 zero-match deps stripped. cargo check --workspace --release clean after each batch
   (s103/s104 transitive-feature trap check — no breakage).
5. lab smoke: 4 of 4 server (GET /health, /openrpc.json, /.well-known/heroservice.json, POST /rpc system.ping)
   + 2 of 2 admin (GET /health, /.well-known/heroservice.json) = 6/6 passed. cargo test
   --workspace --release: 0 failed, 0 passed, 3 ignored (live-server integration tests).

Wholesale canonical-base migration on 3 main.rs:
- hero_office/src/main.rs (CLI): added service_base!() + validate_service_toml(SERVICE_TOML) +
  handle_info_flag(SERVICE_TOML) before Args::parse(). No bare-invocation shim needed (CLI is
  pure flag-driven `--start`/`--stop` Args; bare invocation defaults to --help).
- hero_office_server/src/main.rs (daemon): added service_base!() + validate + handle_info_flag +
  print_startup_banner + prepare_sockets. Removed manual create_dir_all + remove_file (now
  handled by prepare_sockets). Added /.well-known/heroservice.json route for the new lab smoke
  gate (sibling pattern from hero_collab_server::http_manifest).
- hero_office_admin/src/main.rs (daemon): same canonical wiring as server. Added
  /.well-known/heroservice.json route via handlers::well_known.

3 new service.toml files (per-crate, all-binaries-in-each canonical pattern per
hero_service_toml_info skill line 220 — matches today's hero_proc post-7fcea44 shape):
- crates/hero_office/service.toml         (kind=cli)
- crates/hero_office_server/service.toml  (kind=server, rpc.sock openrpc)
- crates/hero_office_admin/service.toml   (kind=admin, admin.sock http+webui)

Each [[binaries]] block lists all 3 binaries with their sockets and kinds. [[env]] entries
declared for: HERO_SOCKET_DIR (required workaround — see latent below), DEFAULT_CONTEXT,
ONLYOFFICE_JWT_SECRET, CONNECTOR_EXTERNAL_URL, OO_UPSTREAM_BASE, OO_PUBLIC_PROTO.

[[dependencies]] block initially included hero_foundry (server's onlyoffice.rs reads
document mtimes from foundry's UDS) but DROPPED because the installed ~/hero/bin/hero_foundry
is s7x-vintage without --info support, and lab service triggers dep bootstrap. Per the skill
("Most services need no [[dependencies]] at all") and the runtime degradation path at
crates/hero_office_server/src/onlyoffice.rs:63 ("Degraded mode: foundry's last_modified
couldn't be read; using time-bucket fallback"), hero_foundry is a soft dep. Re-add when the
sibling hero_foundry repo gets its own D-10 sweep and --info wiring.

LATENT (out of D-10 scope):
- herolib_core::base::resolve_socket_dir() doc claims a `~/hero/var/sockets` fallback when
  neither HERO_SOCKET_DIR nor PATH_VAR is set, but the impl (service.rs:299-308 post-b814ec07)
  panics via path_var(). This forces every D-10 service.toml to keep an [[env]] entry for
  HERO_SOCKET_DIR even though the hero_service_toml_info skill says not to. Workaround
  honoured here for the supervised-process path. Fix belongs in herolib_core.
- crates/hero_office_server/openrpc.client.generated.rs is committed at a non-canonical path
  (sdk generated files normally live under crates/<sdk>/src/generated/openrpc.client.generated.rs).
  Left in place; reorganisation belongs in a separate refactor.
- Workspace `rust-version = "1.92"` (D-08 SSOT is 1.95). Pre-existing; bump out of D-10 scope.

Refs: lhumina_code/hero_proc#102

Signed-off-by: mik-tf
2026-05-17 03:01:46 -04:00
.forgejo/workflows refactor: rename hero_office_ui -> hero_office_admin (ui.sock -> admin.sock) (#27) 2026-05-08 02:06:08 +00:00
crates chore(hero_office): D-10 sweep — service.toml + herolib_core::base on 3 binaries + cargo update absorb + dep audit 2026-05-17 03:01:46 -04:00
doc refactor: rename hero_office_ui -> hero_office_admin (ui.sock -> admin.sock) (#27) 2026-05-08 02:06:08 +00:00
.gitignore refactor: restructure into Hero multi-crate workspace 2026-04-20 16:09:45 +02:00
buildenv.sh refactor: rename hero_office_ui -> hero_office_admin (ui.sock -> admin.sock) (#27) 2026-05-08 02:06:08 +00:00
Cargo.lock chore(hero_office): D-10 sweep — service.toml + herolib_core::base on 3 binaries + cargo update absorb + dep audit 2026-05-17 03:01:46 -04:00
Cargo.toml refactor: rename hero_office_ui -> hero_office_admin (ui.sock -> admin.sock) (#27) 2026-05-08 02:06:08 +00:00
Makefile refactor: rename hero_office_ui -> hero_office_admin (ui.sock -> admin.sock) (#27) 2026-05-08 02:06:08 +00:00
README.md refactor: rename hero_office_ui -> hero_office_admin (ui.sock -> admin.sock) (#27) 2026-05-08 02:06:08 +00:00

hero_office

OnlyOffice document editor connector for the Hero stack, backed by per-context hero_fossil WebDAV storage.

hero_office hosts OnlyOffice Docs editor surfaces (documents, spreadsheets, presentations, PDFs, diagrams) and persists files through the tenant's hero_fossil instance. The UI is embedded into hero_os as a set of apps under the "Office" archipelago.

Workspace layout

crate role
hero_office_server OpenRPC JSON-RPC daemon on rpc.sock — all business logic
hero_office_sdk Generated typed client via openrpc_client! macro
hero_office_admin HTTP UI on admin.sock — admin dashboard + OnlyOffice wrapper pages
hero_office_examples Examples and integration tests

Sockets

socket purpose
$HERO_SOCKET_DIR/hero_office/rpc.sock server OpenRPC endpoint
$HERO_SOCKET_DIR/hero_office/ui.sock UI HTTP endpoint (iframed)
$HERO_SOCKET_DIR/<context>/hero_fossil_server.sock per-context fossil backend

HERO_SOCKET_DIR defaults to $HOME/hero/var/sockets.

Lifecycle

Managed through hero_proc via the Nushell service module at scripts/nu_service.nu (per the nu_service skill).

use scripts/nu_service.nu

nu_service install   # cargo build --release + copy to ~/hero/bin
nu_service start     # register actions + service, then start
nu_service status
nu_service stop

Environment variables

variable purpose
ONLYOFFICE_JWT_SECRET shared JWT secret for signing editor configs (must match the OO container)
OO_SERVER_URL public URL of the OnlyOffice Docs server (loaded by the user's browser)
CONNECTOR_EXTERNAL_URL URL of this service as seen by the OnlyOffice container
DEFAULT_CONTEXT fallback context shown on / (default: default)
HERO_SOCKET_DIR socket directory (default: $HOME/hero/var/sockets)

URL surface (admin.sock, proxied by hero_router under /hero_office/)

route method purpose
/health GET JSON health check
/admin/?context=<ctx> GET operator dashboard
/<ctx>/<type>/ GET file browser filtered to one OnlyOffice type
/<ctx>/edit/<filename> GET OnlyOffice editor wrapper page
/<ctx>/files/<filename> GET byte proxy for the OO container
/<ctx>/callback POST OnlyOffice save callback

Where <type> is one of word, cell, slide, pdf, diagram.

hero_os integration

The "Office" archipelago (hierarchical) contains five islands, each an iframe pointing at the corresponding filtered surface:

  • Documents → /hero_office/<ctx>/word/
  • Spreadsheets → /hero_office/<ctx>/cell/
  • Presentations → /hero_office/<ctx>/slide/
  • PDF → /hero_office/<ctx>/pdf/
  • Diagrams → /hero_office/<ctx>/diagram/

See hero_os/crates/hero_os_app/src/registry.rs and island_content.rs.