Align OSchema/UDS layout with canonical hero_osis/hero_voice pattern #15

Closed
opened 2026-04-19 21:25:29 +00:00 by mahmoud · 4 comments
Owner

Context

hero_livekit wires OSchema → Rust / OpenRPC / OSIS codegen, but its layout drifts from the canonical pattern used across the Hero ecosystem (hero_osis, hero_voice). The canonical pattern (per oschema_code_generation §4 + §9 and observed in siblings) places schemas/, docs/schemas/, and sdk/ at the workspace root and uses a richer build.rs that auto-generates the SDK client crate and declares the CLI/companion/UI layout so the multi-socket OServer wiring comes for free.

Canonical reference — hero_voice

hero_voice/
├── schemas/voice/voice.oschema             # workspace root
├── docs/schemas/                            # workspace root
├── sdk/js/                                  # workspace root (JS SDK output)
└── crates/
    ├── hero_voice/                          # core crate: build.rs + generated types
    │   ├── build.rs                         # .schemas_dir("../../schemas")
    │   └── src/voice/{core,server,tests}
    ├── hero_voice_server/                   # bin: Unix socket + JSON-RPC dispatch
    ├── hero_voice_sdk/                      # SDK: openrpc_client!("../hero_voice_server/openrpc.json")
    ├── hero_voice_ui/
    ├── hero_voice_app/                      # CLI (hero_proc self-start)
    └── hero_voice_examples/

Canonical reference — hero_osis build.rs extras

OschemaBuildConfig::new()
    .schemas_dir("../../schemas")
    .docs_dir("../../docs/schemas")
    .sdk_dir("../../sdk")
    .client_crate_dir("../hero_osis_sdk")
    .nested_layout()
    .single_bin("hero_osis", "Hero OSIS", "<repo url>", "<desc>")
    .bin_companions(["hero_osis_ui"])
    .bin_ui("hero_osis_ui::build_router")
    .generate_server();

These flags make the generator emit: (a) the SDK crate's client code directly into ../hero_osis_sdk/src/…, (b) the single-bin CLI registering rpc.sock + ui.sock per domain with the admin UI router mounted in-process.

Current hero_livekit layout (drift)

  • crates/hero_livekit_server/schemas/livekit/livekit.oschema — nested inside server crate
  • crates/hero_livekit_server/docs/schemas/ — nested inside server crate
  • crates/hero_livekit_server/sdk/js/ — nested inside server crate
  • crates/hero_livekit_server/build.rs — runs codegen; lives in the server crate, not a core crate
  • build.rs uses only .schemas_dir("schemas").docs_dir("docs/schemas").domain("livekit", ...).generate_server().nested_layout().debug(true)missing client_crate_dir, sdk_dir, single_bin, bin_companions, bin_ui, sdk_types_crate
  • Generated openrpc.json sits at src/livekit/core/openrpc.json (deeply nested) instead of at the server crate root next to main.rs (like hero_voice_server/openrpc.json)
  • No separate hero_livekit_sdk crate → UI and examples reach into the server crate for client types (coupling violation — see also issue #3)

Why it matters

  • Cross-crate imports break — the openrpc_client! macro in a future hero_livekit_sdk wants the OpenRPC spec at a stable relative path. Siblings follow crates/<svc>_server/openrpc.json.
  • Multi-socket UDS wiring.single_bin + .bin_ui is how the multi-socket OServer gets generated (per-domain rpc.sock + ui.sock, with X-Hero-Context / X-Hero-Claims / X-Forwarded-Prefix headers handled for free). Without these, the CLI in issue #1 will have to re-implement wiring the generator already produces.
  • Documentation + JS SDK publish — repo-root docs/schemas/ + sdk/ is what Hero's doc tooling scans.

Goals

  • Promote schemas to workspace root — move crates/hero_livekit_server/schemas/schemas/livekit/livekit.oschema.
  • Promote docs/schemas to workspace root — move crates/hero_livekit_server/docs/schemas/docs/schemas/.
  • Promote js sdk to workspace root — move crates/hero_livekit_server/sdk/js/sdk/js/.
  • Create crates/hero_livekit/ (core crate) — thin crate that hosts build.rs and exposes hero_livekit::livekit::{core, server} generated modules. Move build.rs here; server crate depends on it.
  • Relocate openrpc.json — emit/copy to crates/hero_livekit_server/openrpc.json next to main.rs (matching hero_voice_server), not nested under src/livekit/core/.
  • Rewrite build.rs (in the new core crate) to:
    OschemaBuildConfig::new()
        .schemas_dir("../../schemas")
        .docs_dir("../../docs/schemas")
        .sdk_dir("../../sdk")
        .domain("livekit", "LiveKit SFU orchestration and room management")
        .generate_server()
        .with_wasm()
        .nested_layout()
        .client_crate_dir("../hero_livekit_sdk")
        .sdk_types_crate("hero_livekit")
        .single_bin(
            "hero_livekit",
            "Hero LiveKit",
            "https://forge.ourworld.tf/lhumina_code/hero_livekit.git",
            "Hero LiveKit — SFU orchestration + room/participant management",
        )
        .bin_companions(["hero_livekit_ui"])
        .bin_ui("hero_livekit_ui::build_router")
        .debug(false);
    
  • Wire the generated SDK cratecrates/hero_livekit_sdk/Cargo.toml + src/lib.rs that calls openrpc_client!("../hero_livekit_server/openrpc.json") and re-exports core types from hero_livekit (see #3).
  • Server main.rs — replace include_str!("../../hero_livekit_server/src/livekit/core/openrpc.json") style paths with include_str!("../openrpc.json"), matching hero_voice_server/src/main.rs:40.
  • UI + examples — depend on hero_livekit_sdk, drop any direct openrpc_client! / hand-rolled clients.
  • Update workspace Cargo.toml members list and the workspace README / docs pointing at the new schema/doc locations.
  • cargo build --workspace + cargo clippy --workspace -- -D warnings both succeed after the move.

Related skills: oschema, oschema_code_generation, hero_sockets, hero_crates_best_practices_check, hero_stack_getting_started.

Related issues:

  • #1 — CLI self-start (consumes .single_bin() output)
  • #3 — hero_livekit_sdk crate (consumes .client_crate_dir() output)
## Context `hero_livekit` wires OSchema → Rust / OpenRPC / OSIS codegen, but its layout drifts from the canonical pattern used across the Hero ecosystem (`hero_osis`, `hero_voice`). The canonical pattern (per `oschema_code_generation` §4 + §9 and observed in siblings) places `schemas/`, `docs/schemas/`, and `sdk/` at the **workspace root** and uses a richer `build.rs` that auto-generates the SDK client crate and declares the CLI/companion/UI layout so the multi-socket OServer wiring comes for free. ### Canonical reference — `hero_voice` ``` hero_voice/ ├── schemas/voice/voice.oschema # workspace root ├── docs/schemas/ # workspace root ├── sdk/js/ # workspace root (JS SDK output) └── crates/ ├── hero_voice/ # core crate: build.rs + generated types │ ├── build.rs # .schemas_dir("../../schemas") │ └── src/voice/{core,server,tests} ├── hero_voice_server/ # bin: Unix socket + JSON-RPC dispatch ├── hero_voice_sdk/ # SDK: openrpc_client!("../hero_voice_server/openrpc.json") ├── hero_voice_ui/ ├── hero_voice_app/ # CLI (hero_proc self-start) └── hero_voice_examples/ ``` ### Canonical reference — `hero_osis` build.rs extras ```rust OschemaBuildConfig::new() .schemas_dir("../../schemas") .docs_dir("../../docs/schemas") .sdk_dir("../../sdk") .client_crate_dir("../hero_osis_sdk") .nested_layout() .single_bin("hero_osis", "Hero OSIS", "<repo url>", "<desc>") .bin_companions(["hero_osis_ui"]) .bin_ui("hero_osis_ui::build_router") .generate_server(); ``` These flags make the generator emit: (a) the SDK crate's client code directly into `../hero_osis_sdk/src/…`, (b) the single-bin CLI registering rpc.sock + ui.sock per domain with the admin UI router mounted in-process. ### Current `hero_livekit` layout (drift) - `crates/hero_livekit_server/schemas/livekit/livekit.oschema` — nested inside server crate - `crates/hero_livekit_server/docs/schemas/` — nested inside server crate - `crates/hero_livekit_server/sdk/js/` — nested inside server crate - `crates/hero_livekit_server/build.rs` — runs codegen; lives in the server crate, not a core crate - `build.rs` uses only `.schemas_dir("schemas").docs_dir("docs/schemas").domain("livekit", ...).generate_server().nested_layout().debug(true)` — **missing** `client_crate_dir`, `sdk_dir`, `single_bin`, `bin_companions`, `bin_ui`, `sdk_types_crate` - Generated `openrpc.json` sits at `src/livekit/core/openrpc.json` (deeply nested) instead of at the server crate root next to `main.rs` (like `hero_voice_server/openrpc.json`) - No separate `hero_livekit_sdk` crate → UI and examples reach into the server crate for client types (coupling violation — see also issue #3) ### Why it matters - **Cross-crate imports break** — the `openrpc_client!` macro in a future `hero_livekit_sdk` wants the OpenRPC spec at a stable relative path. Siblings follow `crates/<svc>_server/openrpc.json`. - **Multi-socket UDS wiring** — `.single_bin` + `.bin_ui` is how the multi-socket OServer gets generated (per-domain `rpc.sock` + `ui.sock`, with `X-Hero-Context` / `X-Hero-Claims` / `X-Forwarded-Prefix` headers handled for free). Without these, the CLI in issue #1 will have to re-implement wiring the generator already produces. - **Documentation + JS SDK publish** — repo-root `docs/schemas/` + `sdk/` is what Hero's doc tooling scans. ## Goals - **Promote schemas to workspace root** — move `crates/hero_livekit_server/schemas/` → `schemas/livekit/livekit.oschema`. - **Promote docs/schemas to workspace root** — move `crates/hero_livekit_server/docs/schemas/` → `docs/schemas/`. - **Promote js sdk to workspace root** — move `crates/hero_livekit_server/sdk/js/` → `sdk/js/`. - **Create `crates/hero_livekit/` (core crate)** — thin crate that hosts `build.rs` and exposes `hero_livekit::livekit::{core, server}` generated modules. Move `build.rs` here; server crate depends on it. - **Relocate `openrpc.json`** — emit/copy to `crates/hero_livekit_server/openrpc.json` next to `main.rs` (matching `hero_voice_server`), not nested under `src/livekit/core/`. - **Rewrite `build.rs`** (in the new core crate) to: ```rust OschemaBuildConfig::new() .schemas_dir("../../schemas") .docs_dir("../../docs/schemas") .sdk_dir("../../sdk") .domain("livekit", "LiveKit SFU orchestration and room management") .generate_server() .with_wasm() .nested_layout() .client_crate_dir("../hero_livekit_sdk") .sdk_types_crate("hero_livekit") .single_bin( "hero_livekit", "Hero LiveKit", "https://forge.ourworld.tf/lhumina_code/hero_livekit.git", "Hero LiveKit — SFU orchestration + room/participant management", ) .bin_companions(["hero_livekit_ui"]) .bin_ui("hero_livekit_ui::build_router") .debug(false); ``` - **Wire the generated SDK crate** — `crates/hero_livekit_sdk/Cargo.toml` + `src/lib.rs` that calls `openrpc_client!("../hero_livekit_server/openrpc.json")` and re-exports core types from `hero_livekit` (see #3). - **Server `main.rs`** — replace `include_str!("../../hero_livekit_server/src/livekit/core/openrpc.json")` style paths with `include_str!("../openrpc.json")`, matching `hero_voice_server/src/main.rs:40`. - **UI + examples** — depend on `hero_livekit_sdk`, drop any direct `openrpc_client!` / hand-rolled clients. - Update workspace `Cargo.toml` members list and the workspace README / docs pointing at the new schema/doc locations. - `cargo build --workspace` + `cargo clippy --workspace -- -D warnings` both succeed after the move. Related skills: `oschema`, `oschema_code_generation`, `hero_sockets`, `hero_crates_best_practices_check`, `hero_stack_getting_started`. Related issues: - #1 — CLI self-start (consumes `.single_bin()` output) - #3 — hero_livekit_sdk crate (consumes `.client_crate_dir()` output)
Member

Implementation Spec for Issue #15

Objective

Restructure the hero_livekit workspace to match the canonical OSchema layout used by hero_voice and hero_os. This involves promoting schemas, docs, and sdk directories to the workspace root, creating a new hero_livekit core crate that owns the build.rs and domain types, creating a hero_livekit_sdk crate with a generated OSIS client, moving server-specific generated code to the server crate, relocating openrpc.json to the server crate root, and updating all downstream crates that reference the old deeply-nested paths.

Requirements

  • Schemas directory lives at workspace root: schemas/livekit/livekit.oschema
  • Documentation directory lives at workspace root: docs/schemas/
  • JavaScript SDK directory lives at workspace root: sdk/js/
  • A new crates/hero_livekit/ core crate hosts build.rs and exposes generated types/core modules
  • A new crates/hero_livekit_sdk/ crate provides a generated OSIS client
  • build.rs in the core crate uses the full canonical config (client_crate_dir, sdk_dir, single_bin, bin_companions, etc.)
  • openrpc.json is emitted/copied to crates/hero_livekit_server/openrpc.json (next to Cargo.toml)
  • The server crate depends on the core crate and re-exports core types
  • All downstream crates (UI, examples, rhai) reference the new openrpc.json location
  • Workspace Cargo.toml members list includes the two new crates
  • cargo build --workspace and cargo clippy --workspace succeed

Files to Create

File Description
schemas/livekit/livekit.oschema Moved from crates/hero_livekit_server/schemas/livekit/livekit.oschema
crates/hero_livekit/Cargo.toml New core crate manifest
crates/hero_livekit/build.rs Canonical build config with full OSchema options
crates/hero_livekit/src/ Generated by OschemaBuilder (lib.rs, livekit/core/, etc.)
crates/hero_livekit_sdk/Cargo.toml New SDK crate manifest
crates/hero_livekit_sdk/src/lib.rs Generated by build.rs; re-exports domain module

Files to Modify

File Description of Changes
Cargo.toml (workspace root) Add crates/hero_livekit and crates/hero_livekit_sdk to members; add workspace deps
crates/hero_livekit_server/Cargo.toml Add dep on hero_livekit; remove [build-dependencies]
crates/hero_livekit_server/src/livekit/mod.rs Remove core module; re-export types from hero_livekit
crates/hero_livekit_server/src/livekit/server/rpc.rs Update imports to reference hero_livekit types
crates/hero_livekit_server/src/livekit/server/authz.rs Update imports
crates/hero_livekit_ui/src/main.rs Change openrpc_client! path
crates/hero_livekit_examples/examples/basic_usage.rs Change openrpc_client! path
crates/hero_livekit_examples/examples/health.rs Change openrpc_client! path
crates/hero_livekit_rhai/src/client.rs Change openrpc_client! path
docs/architecture.md Update path references
docs/api.md Update path references

Files to Delete

File/Directory Reason
crates/hero_livekit_server/schemas/ Promoted to workspace root
crates/hero_livekit_server/docs/ Promoted to workspace root
crates/hero_livekit_server/sdk/ Promoted to workspace root
crates/hero_livekit_server/build.rs Moved to core crate
crates/hero_livekit_server/src/livekit/core/ Moved to core crate

Implementation Plan

Step 1: Promote schemas, docs/schemas, and sdk to workspace root

Files: schemas/, docs/schemas/, sdk/js/

  • Move crates/hero_livekit_server/schemas/livekit/livekit.oschema to schemas/livekit/livekit.oschema
  • Move crates/hero_livekit_server/docs/schemas/ to docs/schemas/
  • Move crates/hero_livekit_server/sdk/js/types_generated.js to sdk/js/types_generated.js
  • Remove old directories from server crate
    Dependencies: none

Step 2: Create the hero_livekit core crate

Files: crates/hero_livekit/Cargo.toml, crates/hero_livekit/build.rs, crates/hero_livekit/src/

  • Create Cargo.toml with hero_rpc_osis deps
  • Create build.rs with canonical OschemaBuildConfig (schemas_dir, docs_dir, sdk_dir, domain, generate_server, with_wasm, nested_layout, client_crate_dir, sdk_types_crate, single_bin, bin_companions, bin_ui)
  • Optionally add server_crate_dir("../hero_livekit_server") to generate server code in the server crate
    Dependencies: Step 1

Step 3: Create the hero_livekit_sdk crate

Files: crates/hero_livekit_sdk/Cargo.toml, crates/hero_livekit_sdk/src/lib.rs

  • Create Cargo.toml with hero_rpc_derive, hero_rpc_openrpc deps
  • Create initial lib.rs (will be populated by build.rs generator)
    Dependencies: Step 2

Step 4: Update workspace Cargo.toml

Files: Cargo.toml

  • Add crates/hero_livekit and crates/hero_livekit_sdk to members
  • Add workspace deps for hero_livekit and hero_livekit_sdk
    Dependencies: Steps 2, 3

Step 5: Refactor the server crate to depend on the core crate

Files: crates/hero_livekit_server/Cargo.toml, crates/hero_livekit_server/src/livekit/mod.rs, crates/hero_livekit_server/src/livekit/server/rpc.rs, crates/hero_livekit_server/src/livekit/server/authz.rs

  • Add hero_livekit dependency to server Cargo.toml
  • Remove build-dependencies section
  • Delete server build.rs
  • Delete server src/livekit/core/ directory
  • Update livekit/mod.rs to re-export core types from hero_livekit
  • Update import paths in rpc.rs and authz.rs
    Dependencies: Step 4

Step 6: Update downstream crates (UI, examples, rhai)

Files: crates/hero_livekit_ui/src/main.rs, crates/hero_livekit_examples/examples/basic_usage.rs, crates/hero_livekit_examples/examples/health.rs, crates/hero_livekit_rhai/src/client.rs

  • Change openrpc_client! paths from "../hero_livekit_server/src/livekit/core/openrpc.json" to "../hero_livekit_server/openrpc.json"
    Dependencies: Step 5

Step 7: Update documentation

Files: docs/architecture.md, docs/api.md

  • Update references to old nested paths
    Dependencies: Step 5

Step 8: Build, fix, and verify

  • Run cargo build --workspace to trigger code generation
  • Fix any compilation issues (import paths, missing modules)
  • Run cargo clippy --workspace
  • Run cargo test --workspace
    Dependencies: Steps 5, 6, 7

Acceptance Criteria

  • schemas/livekit/livekit.oschema exists at workspace root
  • docs/schemas/ exists at workspace root
  • sdk/js/types_generated.js exists at workspace root
  • crates/hero_livekit/ exists with canonical build.rs
  • crates/hero_livekit_sdk/ exists with generated client code
  • crates/hero_livekit_server/openrpc.json at server crate root
  • No schema/docs/sdk directories remain under server crate
  • No build.rs in server crate
  • Server crate depends on core crate for types
  • All openrpc_client! paths point to new location
  • cargo build --workspace succeeds
  • cargo clippy --workspace succeeds
  • cargo test --workspace passes
  • Workspace Cargo.toml lists all crate members

Notes

  1. Generator version: Stay with hero_rpc_osis::build to minimize churn. A later issue can upgrade to hero_rpc_generator if needed.
  2. server_crate_dir: Recommended to use server_crate_dir("../hero_livekit_server") to keep server-generated code in the server crate (hero_os pattern), since the server has substantial hand-written code (rpc.rs 880+ lines, authz.rs 290+ lines).
  3. bin_ui function: The canonical config references hero_livekit_ui::build_router which does not yet exist. These declarative options can be set now and the actual binary generation addressed in a follow-up.
  4. Import resolution strategy: Use a local pub use hero_livekit::livekit::core as core; re-export in the server's livekit/mod.rs so existing relative imports continue to work.
  5. Preserve hand-written code: rpc.rs and authz.rs have substantial business logic and must not be overwritten by the generator.
## Implementation Spec for Issue #15 ### Objective Restructure the hero_livekit workspace to match the canonical OSchema layout used by hero_voice and hero_os. This involves promoting schemas, docs, and sdk directories to the workspace root, creating a new `hero_livekit` core crate that owns the build.rs and domain types, creating a `hero_livekit_sdk` crate with a generated OSIS client, moving server-specific generated code to the server crate, relocating openrpc.json to the server crate root, and updating all downstream crates that reference the old deeply-nested paths. ### Requirements - Schemas directory lives at workspace root: `schemas/livekit/livekit.oschema` - Documentation directory lives at workspace root: `docs/schemas/` - JavaScript SDK directory lives at workspace root: `sdk/js/` - A new `crates/hero_livekit/` core crate hosts build.rs and exposes generated types/core modules - A new `crates/hero_livekit_sdk/` crate provides a generated OSIS client - build.rs in the core crate uses the full canonical config (client_crate_dir, sdk_dir, single_bin, bin_companions, etc.) - openrpc.json is emitted/copied to `crates/hero_livekit_server/openrpc.json` (next to Cargo.toml) - The server crate depends on the core crate and re-exports core types - All downstream crates (UI, examples, rhai) reference the new openrpc.json location - Workspace Cargo.toml members list includes the two new crates - `cargo build --workspace` and `cargo clippy --workspace` succeed ### Files to Create | File | Description | |------|-------------| | `schemas/livekit/livekit.oschema` | Moved from `crates/hero_livekit_server/schemas/livekit/livekit.oschema` | | `crates/hero_livekit/Cargo.toml` | New core crate manifest | | `crates/hero_livekit/build.rs` | Canonical build config with full OSchema options | | `crates/hero_livekit/src/` | Generated by OschemaBuilder (lib.rs, livekit/core/, etc.) | | `crates/hero_livekit_sdk/Cargo.toml` | New SDK crate manifest | | `crates/hero_livekit_sdk/src/lib.rs` | Generated by build.rs; re-exports domain module | ### Files to Modify | File | Description of Changes | |------|----------------------| | `Cargo.toml` (workspace root) | Add `crates/hero_livekit` and `crates/hero_livekit_sdk` to members; add workspace deps | | `crates/hero_livekit_server/Cargo.toml` | Add dep on `hero_livekit`; remove `[build-dependencies]` | | `crates/hero_livekit_server/src/livekit/mod.rs` | Remove core module; re-export types from hero_livekit | | `crates/hero_livekit_server/src/livekit/server/rpc.rs` | Update imports to reference hero_livekit types | | `crates/hero_livekit_server/src/livekit/server/authz.rs` | Update imports | | `crates/hero_livekit_ui/src/main.rs` | Change openrpc_client! path | | `crates/hero_livekit_examples/examples/basic_usage.rs` | Change openrpc_client! path | | `crates/hero_livekit_examples/examples/health.rs` | Change openrpc_client! path | | `crates/hero_livekit_rhai/src/client.rs` | Change openrpc_client! path | | `docs/architecture.md` | Update path references | | `docs/api.md` | Update path references | ### Files to Delete | File/Directory | Reason | |----------------|--------| | `crates/hero_livekit_server/schemas/` | Promoted to workspace root | | `crates/hero_livekit_server/docs/` | Promoted to workspace root | | `crates/hero_livekit_server/sdk/` | Promoted to workspace root | | `crates/hero_livekit_server/build.rs` | Moved to core crate | | `crates/hero_livekit_server/src/livekit/core/` | Moved to core crate | ### Implementation Plan #### Step 1: Promote schemas, docs/schemas, and sdk to workspace root Files: `schemas/`, `docs/schemas/`, `sdk/js/` - Move `crates/hero_livekit_server/schemas/livekit/livekit.oschema` to `schemas/livekit/livekit.oschema` - Move `crates/hero_livekit_server/docs/schemas/` to `docs/schemas/` - Move `crates/hero_livekit_server/sdk/js/types_generated.js` to `sdk/js/types_generated.js` - Remove old directories from server crate Dependencies: none #### Step 2: Create the hero_livekit core crate Files: `crates/hero_livekit/Cargo.toml`, `crates/hero_livekit/build.rs`, `crates/hero_livekit/src/` - Create Cargo.toml with hero_rpc_osis deps - Create build.rs with canonical OschemaBuildConfig (schemas_dir, docs_dir, sdk_dir, domain, generate_server, with_wasm, nested_layout, client_crate_dir, sdk_types_crate, single_bin, bin_companions, bin_ui) - Optionally add server_crate_dir("../hero_livekit_server") to generate server code in the server crate Dependencies: Step 1 #### Step 3: Create the hero_livekit_sdk crate Files: `crates/hero_livekit_sdk/Cargo.toml`, `crates/hero_livekit_sdk/src/lib.rs` - Create Cargo.toml with hero_rpc_derive, hero_rpc_openrpc deps - Create initial lib.rs (will be populated by build.rs generator) Dependencies: Step 2 #### Step 4: Update workspace Cargo.toml Files: `Cargo.toml` - Add `crates/hero_livekit` and `crates/hero_livekit_sdk` to members - Add workspace deps for hero_livekit and hero_livekit_sdk Dependencies: Steps 2, 3 #### Step 5: Refactor the server crate to depend on the core crate Files: `crates/hero_livekit_server/Cargo.toml`, `crates/hero_livekit_server/src/livekit/mod.rs`, `crates/hero_livekit_server/src/livekit/server/rpc.rs`, `crates/hero_livekit_server/src/livekit/server/authz.rs` - Add hero_livekit dependency to server Cargo.toml - Remove build-dependencies section - Delete server build.rs - Delete server src/livekit/core/ directory - Update livekit/mod.rs to re-export core types from hero_livekit - Update import paths in rpc.rs and authz.rs Dependencies: Step 4 #### Step 6: Update downstream crates (UI, examples, rhai) Files: `crates/hero_livekit_ui/src/main.rs`, `crates/hero_livekit_examples/examples/basic_usage.rs`, `crates/hero_livekit_examples/examples/health.rs`, `crates/hero_livekit_rhai/src/client.rs` - Change openrpc_client! paths from `"../hero_livekit_server/src/livekit/core/openrpc.json"` to `"../hero_livekit_server/openrpc.json"` Dependencies: Step 5 #### Step 7: Update documentation Files: `docs/architecture.md`, `docs/api.md` - Update references to old nested paths Dependencies: Step 5 #### Step 8: Build, fix, and verify - Run `cargo build --workspace` to trigger code generation - Fix any compilation issues (import paths, missing modules) - Run `cargo clippy --workspace` - Run `cargo test --workspace` Dependencies: Steps 5, 6, 7 ### Acceptance Criteria - [ ] `schemas/livekit/livekit.oschema` exists at workspace root - [ ] `docs/schemas/` exists at workspace root - [ ] `sdk/js/types_generated.js` exists at workspace root - [ ] `crates/hero_livekit/` exists with canonical build.rs - [ ] `crates/hero_livekit_sdk/` exists with generated client code - [ ] `crates/hero_livekit_server/openrpc.json` at server crate root - [ ] No schema/docs/sdk directories remain under server crate - [ ] No build.rs in server crate - [ ] Server crate depends on core crate for types - [ ] All openrpc_client! paths point to new location - [ ] `cargo build --workspace` succeeds - [ ] `cargo clippy --workspace` succeeds - [ ] `cargo test --workspace` passes - [ ] Workspace Cargo.toml lists all crate members ### Notes 1. **Generator version**: Stay with `hero_rpc_osis::build` to minimize churn. A later issue can upgrade to `hero_rpc_generator` if needed. 2. **server_crate_dir**: Recommended to use `server_crate_dir("../hero_livekit_server")` to keep server-generated code in the server crate (hero_os pattern), since the server has substantial hand-written code (rpc.rs 880+ lines, authz.rs 290+ lines). 3. **bin_ui function**: The canonical config references `hero_livekit_ui::build_router` which does not yet exist. These declarative options can be set now and the actual binary generation addressed in a follow-up. 4. **Import resolution strategy**: Use a local `pub use hero_livekit::livekit::core as core;` re-export in the server's livekit/mod.rs so existing relative imports continue to work. 5. **Preserve hand-written code**: rpc.rs and authz.rs have substantial business logic and must not be overwritten by the generator.
Member

Test Results

  • cargo build --workspace: PASS
  • cargo clippy --workspace -- -D warnings: PASS
  • cargo test --workspace: PASS -- 34 tests passed, 0 failed, 4 doc-tests ignored

Test breakdown

Crate Tests Result
hero_livekit (core) 4 CRUD tests PASS
hero_livekit_server (lib) 15 tests (4 CRUD + 11 authz) PASS
hero_livekit_server (bin) 15 tests (4 CRUD + 11 authz) PASS
hero_livekit_sdk 0 (generated code) PASS
hero_livekit_rhai 0 PASS

All existing tests pass after the restructuring.

## Test Results - `cargo build --workspace`: PASS - `cargo clippy --workspace -- -D warnings`: PASS - `cargo test --workspace`: PASS -- 34 tests passed, 0 failed, 4 doc-tests ignored ### Test breakdown | Crate | Tests | Result | |-------|-------|--------| | hero_livekit (core) | 4 CRUD tests | PASS | | hero_livekit_server (lib) | 15 tests (4 CRUD + 11 authz) | PASS | | hero_livekit_server (bin) | 15 tests (4 CRUD + 11 authz) | PASS | | hero_livekit_sdk | 0 (generated code) | PASS | | hero_livekit_rhai | 0 | PASS | All existing tests pass after the restructuring.
Member

Implementation Summary

Changes Made

New crates created:

  • crates/hero_livekit/ -- Core crate with build.rs, generated types, server logic, and domain handlers
  • crates/hero_livekit_sdk/ -- Generated OSIS client crate with LivekitClient for consuming the API

Directories promoted to workspace root:

  • schemas/livekit/livekit.oschema (was crates/hero_livekit_server/schemas/)
  • docs/schemas/ (was crates/hero_livekit_server/docs/schemas/)
  • sdk/js/types_generated.js (was crates/hero_livekit_server/sdk/js/)

Server crate refactored:

  • Removed build.rs (moved to core crate)
  • Removed src/livekit/core/ directory (types now live in core crate)
  • Added dependency on hero_livekit core crate
  • Re-exports core types and server handlers from the core crate
  • Kept authz.rs (authorization wrapper) in the server crate
  • openrpc.json now at server crate root (was deeply nested at src/livekit/core/openrpc.json)

Core crate build.rs uses full canonical config:

  • schemas_dir, docs_dir, sdk_dir pointing to workspace root
  • client_crate_dir auto-generates SDK crate code
  • sdk_types_crate, single_bin, bin_companions, bin_ui declared for future use
  • generate_server(), with_wasm(), nested_layout()

Downstream crates updated:

  • hero_livekit_ui, hero_livekit_examples, hero_livekit_rhai -- openrpc_client! paths updated to "../hero_livekit_server/openrpc.json"

Documentation updated:

  • docs/architecture.md -- updated code layout diagram
  • docs/api.md -- updated spec and schema paths

Workspace Cargo.toml:

  • Added crates/hero_livekit and crates/hero_livekit_sdk to members
  • Added hero_livekit, hero_livekit_sdk, hero_rpc_client, herolib_otoml to workspace dependencies

Test Results

  • cargo build --workspace: PASS
  • cargo clippy --workspace -- -D warnings: PASS
  • cargo test --workspace: 34 tests passed, 0 failed

Notes

  • The single_bin option in build.rs generates a src/bin/hero_livekit.rs orchestrator binary. This was removed (via autobins = false) as it requires hero_livekit_ui::build_router which does not yet exist. The CLI self-start binary will be addressed in issue #1.
  • The generated SDK uses hero_rpc_client::OsisClient (cross-platform client) rather than the openrpc_client! macro. Downstream crates can migrate to hero_livekit_sdk in a follow-up.
## Implementation Summary ### Changes Made **New crates created:** - `crates/hero_livekit/` -- Core crate with build.rs, generated types, server logic, and domain handlers - `crates/hero_livekit_sdk/` -- Generated OSIS client crate with `LivekitClient` for consuming the API **Directories promoted to workspace root:** - `schemas/livekit/livekit.oschema` (was `crates/hero_livekit_server/schemas/`) - `docs/schemas/` (was `crates/hero_livekit_server/docs/schemas/`) - `sdk/js/types_generated.js` (was `crates/hero_livekit_server/sdk/js/`) **Server crate refactored:** - Removed `build.rs` (moved to core crate) - Removed `src/livekit/core/` directory (types now live in core crate) - Added dependency on `hero_livekit` core crate - Re-exports core types and server handlers from the core crate - Kept `authz.rs` (authorization wrapper) in the server crate - `openrpc.json` now at server crate root (was deeply nested at `src/livekit/core/openrpc.json`) **Core crate build.rs uses full canonical config:** - `schemas_dir`, `docs_dir`, `sdk_dir` pointing to workspace root - `client_crate_dir` auto-generates SDK crate code - `sdk_types_crate`, `single_bin`, `bin_companions`, `bin_ui` declared for future use - `generate_server()`, `with_wasm()`, `nested_layout()` **Downstream crates updated:** - `hero_livekit_ui`, `hero_livekit_examples`, `hero_livekit_rhai` -- `openrpc_client!` paths updated to `"../hero_livekit_server/openrpc.json"` **Documentation updated:** - `docs/architecture.md` -- updated code layout diagram - `docs/api.md` -- updated spec and schema paths **Workspace Cargo.toml:** - Added `crates/hero_livekit` and `crates/hero_livekit_sdk` to members - Added `hero_livekit`, `hero_livekit_sdk`, `hero_rpc_client`, `herolib_otoml` to workspace dependencies ### Test Results - `cargo build --workspace`: PASS - `cargo clippy --workspace -- -D warnings`: PASS - `cargo test --workspace`: 34 tests passed, 0 failed ### Notes - The `single_bin` option in build.rs generates a `src/bin/hero_livekit.rs` orchestrator binary. This was removed (via `autobins = false`) as it requires `hero_livekit_ui::build_router` which does not yet exist. The CLI self-start binary will be addressed in issue #1. - The generated SDK uses `hero_rpc_client::OsisClient` (cross-platform client) rather than the `openrpc_client!` macro. Downstream crates can migrate to `hero_livekit_sdk` in a follow-up.
Member

Pull request opened: #18

This PR implements the changes discussed in this issue.

Pull request opened: https://forge.ourworld.tf/lhumina_code/hero_livekit/pulls/18 This PR implements the changes discussed in this issue.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
2 participants
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_livekit#15
No description provided.