Scaffold full service repo from template (hero_rpc scaffold) #54
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_rpc#54
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?
Goal
Give hero_rpc a first-class scaffolding capability that produces an entire new Hero service repo aligned with current standards — so a contributor (or AI agent) can go from
oschemato a running, lab-installable service in minutes.This is separate from the codegen capability (see #55) which runs after scaffolding, every build.
Reference services
These are the services to mimic. Pull
developmentbranch first.hero_proc(repo)service_base!(),validate_service_toml,handle_info_flag, embeddedservice.toml.PURPOSE.mdis the canonical example of that doc.hero_compute(repo)Cargo.toml._server/src/main.rsuses an olderrun/start/stop/status/servesubcommand pattern with noservice_base!()— do NOT carry that over. Wiring must followhero_proc.Note:
hero_inspectoris out-of-date and intentionally left out as a reference.Alignment with hero_skills (must satisfy
lab infocheck)The scaffolded output must pass these skills clean with zero manual edits:
skills/hero/service/hero_service.md— startup banner,--info,--help,BUILD_NRviaoption_env!("HERO_BUILD_NR").skills/hero/service/hero_service_toml_info.md—service.tomlschema (herolib_core::base::ServiceToml),service_base!()macro,--infoflag contract, closed enums (Kind,Category,Protocol,SockType).skills/hero/service/hero_service_check_fix.md—lab infocheck, socket paths under$HERO_SOCKET_DIR/<service>/<type>.sock, naming suffixes (_server/_admin/_sdk/_web/_app), noMakefile/scripts/*.sh/service_<name>.nu.skills/hero/...herolib_baseskill —print_startup_bannerandprepare_socketsfromherolib_core::base(no hand-rolled equivalents).skills/forge-release-workflow—.forgejo/workflows/build-linux.yaml.skills/hero/sockets—HERO_SOCKET_DIRconventions and the router homepage card naming rule (admin.sock/web_<name>.sock, never bareweb.sock).What to generate
Given an input (service name + initial
.oschemafile + optional flags), produce a complete repo:Cargo.tomlworkspace (resolver = "3", edition 2024, rust-version 1.92+, deps fromhero_computeas a starting point)crates/hero_<name>_server/— RPC daemon (binary). Wiring mirrorshero_proc_server/src/main.rs.crates/hero_<name>_sdk/— generated client SDK (see #55).crates/hero_<name>_admin/— admin UI binary wired tohero_website_lib. Templates use Askama by default — Hero ecosystem default is compile-time Askama (matcheshero_proc_admin). Tera is reserved for cases that genuinely need runtime template loading (user-editable content like blog posts); none of the default admin screens do. The scaffolded_adminconsumes framework default screens as-is even ifhero_website_framework's own existing templates remain Tera until separately migrated.crates/hero_<name>_examples/— runnable examples crate using the generated SDK.crates/hero_<name>/— CLI client. Only generated if the user opts in (--cliflag). Perhero_service_check_fix§5, a CLI that only doesselfstartprovides no value and must be omitted.service.tomlat each crate root.schemas/<domain>/<domain>.oschemaseeded from input.src/main.rspre-wired withservice_base!(),validate_service_toml(SERVICE_TOML),handle_info_flag(SERVICE_TOML),print_startup_banner,prepare_sockets— no hand-rolled equivalents.build.rsreduced to ≤5 lines (depends on #56).README.md— overview, quickstart, referenceslab service <name> --startonly (nevermake, never bash scripts).PURPOSE.md— repo-level document listing components, internal crates, key features, lifecycle commands. Required byhero_service_check_fix§1 ("ReadPURPOSE.mdto know which components exist, if it doesn't exist generate it"). Model the file onhero_proc/PURPOSE.md: tables forBinary | Role | SocketandCrate | Role, then a short "Key Features" section. Lifecycle commands must only referencelab service ...(§6 of the check skill)..gitignore,.forgejo/workflows/build-linux.yamlperforge-release-workflowskill.Makefile, noscripts/*.sh, noservice_<name>.nu(ADR-0001).Naming
Follow the table in
hero_skills/skills/hero/service/hero_service_check_fix.md§2:hero_<name>_serverhero_<name>_adminhero_<name>_sdk(lib)hero_<name>hero_<name>_webNever
_ui,_cli,_cmd.CLI surface
Exposing this as
lab service new <name>is a separate follow-up issue (to be opened against this repo orhero_skillsonce this scaffold capability lands).Out of scope
lab service newsubcommand (follow-up).Acceptance
hero_rpc scaffold tasks --schema sample.oschema --out /tmp/hero_tasksproduces a workspace wherecargo build && lab infocheckboth succeed with zero manual edits.service.tomldeserialises intoherolib_core::base::ServiceToml.--infoand--info --jsonfrom its embeddedservice.toml(no hand-rolled JSON shape)._adminbinary serves the framework default templates atadmin.sock._serverbinary passes the smoke tests inhero_service_check_fix.md§7 (/health,/openrpc.json,/.well-known/heroservice.json, JSON-RPCsystem.ping).lab service <name> --install && lab service <name> --startsucceeds.PURPOSE.mdandREADME.mdexist and reference onlylab service ...commands for lifecycle.Related
generator/src/build/build.rs(lets the scaffoldedbuild.rsbe ≤5 lines).example/recipe_server(consumes this end-to-end)._adminwill inherit.hero_admin_libalias (so scaffolded_adminimports the canonical name).hero_servicetemplate repo (consumes this scaffold).hero_proc(wiring),hero_compute(layout + deps).hero_skills/skills/hero/service/.Lets double check that the scaffolded repo we want to create is aligned with latest standards and best practices from hero_skills. What is the purpose of PURPOSE.md stubs and what do they do, where are they mentioned? CLI Surface is good, and exposing this as lab sub command can be an issue that follows. lets also update the initial issue description related section to properly link to other issues and repos.
Parent / context tracker: hero_skills#262 — read it before starting work on this issue. Locked decisions, reference materials, and execution order live there. Iterate via comments here; consolidation passes on the body only after feedback settles.
Existing scaffolder — context for agents
I missed that this repo already has a scaffolder. On latest
development:crates/generator/src/build/scaffold.rs— 1208 lines, exposesWorkspaceScaffolder. Today it generates a 5-crate workspace:This issue is now: extend + correct
WorkspaceScaffolder, not build from scratch. Required deltas (all of these are locked decisions from the META — hero_skills#262):_client→_sdk. Update all references in the scaffolder._ui→_admin. Update method names (with_ui()/generate_ui/generate_ui_crate) accordingly.hero_<name>_examples/crate generation (runnable SDK usage examples).service.tomlper binary crate (server, admin) matchingherolib_core::base::ServiceToml._adminagainsthero_admin_lib(Axum + rust-embed, not Tera/SQLite).main.rswithservice_base!(),validate_service_toml,handle_info_flag,print_startup_banner,prepare_sockets(per hero_proc reference).labis the single lifecycle tool — noMakefile, noscripts/*.sh, noservice_<name>.nu).PURPOSE.md(perhero_service_check_fixskill §1) andREADME.mdthat reference onlylab service ...for lifecycle..forgejo/workflows/build-linux.yamlperforge-release-workflowskill.example/recipe_serverto end-to-end demo of new pattern #57hero_servicetemplate repo (toy domain: managing Hero services) #261#54 remaining scope landed on
issue-54-scaffold-extendBranched off
issue-55-codegen-alignmentper the META directive (#54 builds on #55 wiring). Single commit,3cd7605.Deltas (all in
crates/generator/src/build/scaffold.rs)Makefile+buildenv.shgeneration (ADR-0001)hero_<name>_examples/crate (Cargo.toml+src/lib.rs+examples/01_connect.rs)PURPOSE.mdmodelled onhero_proc/PURPOSE.md—Binary | Role | SocketandCrate | Roletables, Key Features, Service Management, lifecycle =lab service ...onlyREADME.md— quickstart, components, domains, smoke test; lifecycle =lab service ...only (nomake, no bash, no nu).gitignore.forgejo/workflows/build-linux.yamlperforge-release-workflowskill (self-contained Rust variant, tag → musl release binaries)Bonus: unblock
lab infocheckThe pre-#54 scaffolder shipped
crates/hero_<name>/andcrates/hero_<name>_sdk/without asrc/lib.rs, socargo metadataerrored out with "no targets specified in the manifest" beforebuild.rscodegen had a chance to fill them in. That madelab infocheck(and every workspace-wide tool) abort on the very first crate. Added 2-linepub mod services;stubs that the OSchema generator then enriches on the first build. No other changes needed.Acceptance —
lab infocheckclean, zero manual editsTests
10 new scaffold tests against the on-disk artefacts (replacing the prior unit-only style).
cargo test -p hero_rpc_generator→ 121 passed, 1 ignored (was 110).cargo fmt --checkclean.Out-of-scope items flagged for follow-up
Not done here, by design:
--no-admin/--no-sdk/--cli/--from-service-toml/--outas listed in the issue body. The existing--no-admin/--no-rhaialready work; the new flags are CLI-binary edits, not scaffolder logic. Will be its own small commit if needed before the PR opens._rhaito a different suffix — the issue body doesn't ask for this; current_rhaimatches the existing pattern.cargo build && lab infocheck—cargo buildagainst the scaffolded workspace can't pass in CI today because the generated crates pinhero_lifecycle/hero_admin_libtobranch = "development", and #55'shero_lifecyclerename hasn't merged yet. Will pass automatically once #55 merges todevelopment.lab infocheckdoes pass right now (it only needscargo metadata, not a full build).Branch
issue-54-scaffold-extend— based onissue-55-codegen-alignment. Should be merged via PR after the #55 PR lands ondevelopment(or rebased ontodevelopmentif #55 is merged first).