Restructure SDK outputs into sdk/{rust,rhai,python,js}/ (#70) #89

Merged
timur merged 2 commits from issue-70-sdk-restructure into development 2026-05-20 09:35:44 +00:00
Owner

Closes #70.

Summary

Unifies generated SDK output into a single sdk/ umbrella, one folder per language target. Previously the Rust SDK lived under crates/<name>_sdk/, the Rhai bindings under crates/<name>_rhai/, JS output was a loose sdk/js/types_generated.js, and Python was emitted at all only when the user manually opted in.

After this PR:

sdk/
├── rust/    # Rust SDK crate (was crates/<name>_sdk)
├── rhai/    # Rhai bindings crate (was crates/<name>_rhai)
├── python/  # Python SDK package — emitted by default in scaffolded build.rs
└── js/      # JS/TS ESM package (package.json + src/<domain>.js + barrel)

Cargo package names inside sdk/rust/ and sdk/rhai/ keep their _sdk / _rhai suffix per hero_rpc#55 §6 — only the on-disk directory moved. crates/ keeps the binaries + core lib + examples.

Changes

crates/generator/src/build/scaffold.rs

  • Workspace Cargo.toml members updated to sdk/rust and sdk/rhai.
  • create_workspace_dirs creates sdk/rust/, sdk/rust/src/, and (when Rhai is enabled) sdk/rhai/src/.
  • generate_sdk_crate writes to sdk/rust/; generate_rhai_crate writes to sdk/rhai/.
  • Scaffolded crates/<name>/build.rs now sets client_crate_dir("../../sdk/rust") and calls .with_python_sdk().
  • _examples crate's path dep moved to ../../sdk/rust.
  • README + PURPOSE layout snippets reflect the new umbrella.
  • New focused tests: test_scaffold_unified_sdk_layout, test_workspace_cargo_toml_uses_sdk_paths, test_scaffold_build_rs_opts_into_python_and_sdk_rust.

crates/generator/src/generate/js.rs

  • Output is now a proper ESM package: sdk/js/package.json (preserved on re-run) + per-domain sdk/js/src/<domain>.js + an auto-regenerated sdk/js/src/index.js barrel.
  • New tests covering the package shape and the preserved-package.json behaviour.

crates/generator/src/build/emit/python_sdk.rs

  • Fixes a hero_hero_*_sdk double-prefix bug surfaced by the regen: when sdk_types_crate("hero_recipes") was set (the value the scaffolder always emits), the Python emitter unconditionally prepended another hero_. Now the leading hero_ is stripped before being re-applied, so both bare and prefixed crate names land at sdk/python/hero_<svc>_sdk/. New test python_sdk_strips_redundant_hero_prefix_in_package_name.

example/recipe_server/

  • Regenerated against the new layout: sdk/rust/, sdk/rhai/, brand-new sdk/python/hero_recipes_sdk/, and a proper sdk/js/ package.
  • Workspace Cargo.toml, _examples path dep, and crates/hero_recipes/build.rs updated.
  • README + PURPOSE updated for the new tree.

Out of scope

  • hero_skillshero_service_scaffold.md skill update will land as a separate PR there.
  • hero_service template repo — separate regen PR in that repo.

Acceptance

  • cargo build --workspace — clean (1 pre-existing unused-imports warning in generated types_generated.rs, untouched).
  • cargo test -p hero_rpc_generator --lib — 131 passed; 0 failed.
  • lab infocheck — identical to development (4 clean, 2 with pre-existing issues in crates/generator + crates/hero_lifecycle main.rs §5 boilerplate — out of scope for #70).
  • <hero-api-docs> still resolves: docs/openrpc.json regeneration intact, recipes_admin/src/main.rs still include_str!s it correctly.

Test plan

  • cargo build --workspace from the hero_rpc root
  • cargo build --workspace from example/recipe_server
  • cargo test -p hero_rpc_generator --lib
  • lab infocheck — no new failures vs development
  • Inspect example/recipe_server/sdk/ tree — rust/, rhai/, python/, js/ all populated correctly; no crates/hero_recipes_{sdk,rhai}/ left over

🤖 Generated with Claude Code

Closes #70. ## Summary Unifies generated SDK output into a single `sdk/` umbrella, one folder per language target. Previously the Rust SDK lived under `crates/<name>_sdk/`, the Rhai bindings under `crates/<name>_rhai/`, JS output was a loose `sdk/js/types_generated.js`, and Python was emitted at all only when the user manually opted in. After this PR: ``` sdk/ ├── rust/ # Rust SDK crate (was crates/<name>_sdk) ├── rhai/ # Rhai bindings crate (was crates/<name>_rhai) ├── python/ # Python SDK package — emitted by default in scaffolded build.rs └── js/ # JS/TS ESM package (package.json + src/<domain>.js + barrel) ``` Cargo package names inside `sdk/rust/` and `sdk/rhai/` keep their `_sdk` / `_rhai` suffix per hero_rpc#55 §6 — only the on-disk directory moved. `crates/` keeps the binaries + core lib + examples. ## Changes **`crates/generator/src/build/scaffold.rs`** - Workspace `Cargo.toml` members updated to `sdk/rust` and `sdk/rhai`. - `create_workspace_dirs` creates `sdk/rust/`, `sdk/rust/src/`, and (when Rhai is enabled) `sdk/rhai/src/`. - `generate_sdk_crate` writes to `sdk/rust/`; `generate_rhai_crate` writes to `sdk/rhai/`. - Scaffolded `crates/<name>/build.rs` now sets `client_crate_dir("../../sdk/rust")` and calls `.with_python_sdk()`. - `_examples` crate's path dep moved to `../../sdk/rust`. - README + PURPOSE layout snippets reflect the new umbrella. - New focused tests: `test_scaffold_unified_sdk_layout`, `test_workspace_cargo_toml_uses_sdk_paths`, `test_scaffold_build_rs_opts_into_python_and_sdk_rust`. **`crates/generator/src/generate/js.rs`** - Output is now a proper ESM package: `sdk/js/package.json` (preserved on re-run) + per-domain `sdk/js/src/<domain>.js` + an auto-regenerated `sdk/js/src/index.js` barrel. - New tests covering the package shape and the preserved-package.json behaviour. **`crates/generator/src/build/emit/python_sdk.rs`** - Fixes a `hero_hero_*_sdk` double-prefix bug surfaced by the regen: when `sdk_types_crate("hero_recipes")` was set (the value the scaffolder always emits), the Python emitter unconditionally prepended another `hero_`. Now the leading `hero_` is stripped before being re-applied, so both bare and prefixed crate names land at `sdk/python/hero_<svc>_sdk/`. New test `python_sdk_strips_redundant_hero_prefix_in_package_name`. **`example/recipe_server/`** - Regenerated against the new layout: `sdk/rust/`, `sdk/rhai/`, brand-new `sdk/python/hero_recipes_sdk/`, and a proper `sdk/js/` package. - Workspace `Cargo.toml`, `_examples` path dep, and `crates/hero_recipes/build.rs` updated. - README + PURPOSE updated for the new tree. ## Out of scope * `hero_skills` — `hero_service_scaffold.md` skill update will land as a separate PR there. * `hero_service` template repo — separate regen PR in that repo. ## Acceptance * `cargo build --workspace` — clean (1 pre-existing unused-imports warning in generated `types_generated.rs`, untouched). * `cargo test -p hero_rpc_generator --lib` — 131 passed; 0 failed. * `lab infocheck` — identical to `development` (4 clean, 2 with pre-existing issues in `crates/generator` + `crates/hero_lifecycle` main.rs §5 boilerplate — out of scope for #70). * `<hero-api-docs>` still resolves: `docs/openrpc.json` regeneration intact, `recipes_admin/src/main.rs` still `include_str!`s it correctly. ## Test plan - [x] `cargo build --workspace` from the hero_rpc root - [x] `cargo build --workspace` from `example/recipe_server` - [x] `cargo test -p hero_rpc_generator --lib` - [x] `lab infocheck` — no new failures vs `development` - [x] Inspect `example/recipe_server/sdk/` tree — `rust/`, `rhai/`, `python/`, `js/` all populated correctly; no `crates/hero_recipes_{sdk,rhai}/` left over 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(generator): unify SDK output under sdk/{rust,rhai,python,js}/ (#70)
Some checks failed
Test / test (push) Failing after 2m50s
fe21daf1d8
Scaffolder + JS emitter changes only. Recipe server / hero_service
regen lands in follow-up commits.

Scaffolder (`crates/generator/src/build/scaffold.rs`):
- Rust SDK crate moves from `crates/<name>_sdk/` to `sdk/rust/`.
  Cargo package name keeps its `_sdk` suffix per hero_rpc#55 §6.
- Rhai SDK crate moves from `crates/<name>_rhai/` to `sdk/rhai/`.
  Cargo package name keeps its `_rhai` suffix.
- Workspace `Cargo.toml` members updated accordingly.
- Scaffolded `crates/<name>/build.rs` now points
  `client_crate_dir` at `../../sdk/rust` and opts into the Python
  SDK via `.with_python_sdk()` so a fresh scaffold also produces
  `sdk/python/`.
- `_examples` crate's path dep now points at `../../sdk/rust`.
- README/PURPOSE layout block reflects the new umbrella.
- Added focused tests for the unified layout.

JS emitter (`crates/generator/src/generate/js.rs`):
- Output is now a real ESM package: `sdk/js/package.json` (preserved)
  + per-domain modules at `sdk/js/src/<domain>.js` + an
  auto-generated `sdk/js/src/index.js` barrel module. Old layout
  was a loose `sdk/js/types_generated.js`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chore(example): migrate recipe_server to sdk/{rust,rhai,python,js}/ (#70)
Some checks failed
Test / test (push) Failing after 2m18s
Test / test (pull_request) Failing after 3m15s
969f225001
Regenerates `example/recipe_server/` against the new unified SDK
layout introduced in the previous commit.

* `crates/hero_recipes_sdk/` → `sdk/rust/`
* `crates/hero_recipes_rhai/` → `sdk/rhai/`
* New `sdk/python/hero_recipes_sdk/` package (emitted by
  `.with_python_sdk()`).
* Old loose `sdk/js/types_generated.js` becomes a proper ESM
  package: `sdk/js/package.json` + per-domain
  `sdk/js/src/<domain>.js` + barrel `sdk/js/src/index.js`.
* Workspace `Cargo.toml` members updated; `_examples` crate's
  path dep now points at `../../sdk/rust`.
* `crates/hero_recipes/build.rs` opts into the Python SDK and
  routes `client_crate_dir` to `../../sdk/rust`.

Bonus: fixes a double-prefix bug in the Python SDK emitter where
`sdk_types_crate("hero_recipes")` produced
`sdk/python/hero_hero_recipes_sdk/`. The leading `hero_` prefix is
now stripped before being re-applied, so both bare and prefixed
crate names land at `sdk/python/hero_<svc>_sdk/`. Tests added.

`cargo build --workspace` on the example tree is clean (one
pre-existing unused-imports warning in the generated
`types_generated.rs`, untouched by this change).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
timur merged commit 2ecd5b7c05 into development 2026-05-20 09:35:44 +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_rpc!89
No description provided.