feat(services): add service_mail.nu lifecycle module (#158) #168

Merged
mahmoud merged 3 commits from development_service_mail into development 2026-04-29 13:16:58 +00:00
Member

Summary

Add tools/modules/services/service_mail.nu — a Nushell lifecycle module for the hero_mail Hero service exposing install | start [--reset] | stop | status. Follows the user-level multi-binary pattern established by service_browser.nu / service_livekit.nu: registers hero_mail_server (RPC) and hero_mail_ui (admin dashboard) as two separate hero_proc actions composed into a hero_mail service. No manager binary. hero_mail_cli is built and shipped to ~/hero/bin/ but not registered as an action.

Closes #158

Companion (canonical-layout work that doesn't block this PR): lhumina_code/hero_mail#1

Changes

  • NEW tools/modules/services/service_mail.nu (307 lines)
    • Constants: SVX_BINARIES = [hero_mail_server, hero_mail_ui, hero_mail_cli], SVX_ACTIONS = [hero_mail_server, hero_mail_ui].
    • svx_server_action / svx_ui_action — pin canonical socket layout ~/hero/var/sockets/hero_mail/{rpc,ui}.sock via --bind unix: / --server unix:// flags in the action script field, working around hero_mail's flat-default socket behavior.
    • svx_check_stalwart — soft preflight for the external Stalwart dependency. Pure-bash TCP probe (</dev/tcp/HOST/PORT, no nc required) to ${HERO_MAIL_STALWART_ENDPOINT:-127.0.0.1:25}, falling back to which stalwart-cli / stalwart-mail / stalwart. Warns but does not fail — hero_mail_server already tolerates Stalwart's absence (returns stalwart_running:false).
    • start summary block prints service / actions / state / sockets / UI URL / Stalwart preflight status / hero_mail_cli path / a four-line test plan, per nu_service_use.
    • TODO comment in svx_check_stalwart references installers.nu::install_bun (#137) as the precedent for a future hard-prereq + auto-install path.

Validation

All parse / load / help-render checks pass — see #158 (comment):

# Check Result
1 nu -c "source tools/modules/services/service_mail.nu; print 'parsed ok'" pass
2 nu -c "use tools/modules/services/mod.nu *; print 'mod.nu ok'" pass
3 help service_mail {install,start,stop,status} pass (4/4)

No automated test infrastructure exists for nu modules in this repo — .forgejo/workflows/build.yaml::scripts/test.sh only validates SKILL.md frontmatter under claude/skills/. Target-host smoke testing (acceptance step "becomes healthy") is a follow-up on a real host with hero_proc running.

Caveats

  • --bind unix: is passed to both the server and UI actions for consistency. If hero_mail_ui rejects --bind, a one-line follow-up can drop it from svx_ui_action.
  • --root is exposed on the public surface for tree-uniformity even though hero_mail itself doesn't need root (Stalwart owns the privileged ports). Documented inline.
## Summary Add `tools/modules/services/service_mail.nu` — a Nushell lifecycle module for the `hero_mail` Hero service exposing `install | start [--reset] | stop | status`. Follows the user-level multi-binary pattern established by `service_browser.nu` / `service_livekit.nu`: registers `hero_mail_server` (RPC) and `hero_mail_ui` (admin dashboard) as **two separate** hero_proc actions composed into a `hero_mail` service. No manager binary. `hero_mail_cli` is built and shipped to `~/hero/bin/` but not registered as an action. ## Related issue Closes https://forge.ourworld.tf/lhumina_code/hero_skills/issues/158 Companion (canonical-layout work that doesn't block this PR): https://forge.ourworld.tf/lhumina_code/hero_mail/issues/1 ## Changes - **NEW** `tools/modules/services/service_mail.nu` (307 lines) - Constants: `SVX_BINARIES = [hero_mail_server, hero_mail_ui, hero_mail_cli]`, `SVX_ACTIONS = [hero_mail_server, hero_mail_ui]`. - `svx_server_action` / `svx_ui_action` — pin canonical socket layout `~/hero/var/sockets/hero_mail/{rpc,ui}.sock` via `--bind unix:` / `--server unix://` flags in the action `script` field, working around hero_mail's flat-default socket behavior. - `svx_check_stalwart` — soft preflight for the external Stalwart dependency. Pure-bash TCP probe (`</dev/tcp/HOST/PORT`, no `nc` required) to `${HERO_MAIL_STALWART_ENDPOINT:-127.0.0.1:25}`, falling back to `which stalwart-cli` / `stalwart-mail` / `stalwart`. Warns but does not fail — `hero_mail_server` already tolerates Stalwart's absence (returns `stalwart_running:false`). - `start` summary block prints service / actions / state / sockets / UI URL / Stalwart preflight status / `hero_mail_cli` path / a four-line test plan, per `nu_service_use`. - TODO comment in `svx_check_stalwart` references `installers.nu::install_bun` (#137) as the precedent for a future hard-prereq + auto-install path. ## Validation All parse / load / help-render checks pass — see https://forge.ourworld.tf/lhumina_code/hero_skills/issues/158#issuecomment-26348: | # | Check | Result | |---|---|---| | 1 | `nu -c "source tools/modules/services/service_mail.nu; print 'parsed ok'"` | pass | | 2 | `nu -c "use tools/modules/services/mod.nu *; print 'mod.nu ok'"` | pass | | 3 | `help service_mail {install,start,stop,status}` | pass (4/4) | No automated test infrastructure exists for nu modules in this repo — `.forgejo/workflows/build.yaml::scripts/test.sh` only validates `SKILL.md` frontmatter under `claude/skills/`. Target-host smoke testing (acceptance step "becomes healthy") is a follow-up on a real host with `hero_proc` running. ## Caveats - `--bind unix:` is passed to **both** the server and UI actions for consistency. If `hero_mail_ui` rejects `--bind`, a one-line follow-up can drop it from `svx_ui_action`. - `--root` is exposed on the public surface for tree-uniformity even though `hero_mail` itself doesn't need root (Stalwart owns the privileged ports). Documented inline.
feat(services): add service_mail.nu lifecycle module
All checks were successful
Build and Publish Skills / build-and-publish (pull_request) Successful in 4s
bca6af511e
Add a Nushell lifecycle module for the hero_mail Hero service exposing
install | start [--reset] | stop | status. Two-action shape (no manager):
registers hero_mail_server (RPC) and hero_mail_ui (admin dashboard) as
separate hero_proc actions composed into a hero_mail service. hero_mail_cli
is built and shipped to ~/hero/bin/ but not registered. Action script fields
pin canonical socket layout ~/hero/var/sockets/hero_mail/{rpc,ui}.sock via
--bind / --server flags so binaries land in the per-service subdir
regardless of their flat-default behavior.

Stalwart is treated as a soft external prerequisite: TCP probe to
${HERO_MAIL_STALWART_ENDPOINT:-127.0.0.1:25} via pure-bash </dev/tcp/...,
fallback to a `which stalwart-cli` lookup. Warns but does not fail when
absent — hero_mail_server already runs in stub mode in that case.

#158
Merge branch 'development' into development_service_mail
All checks were successful
Build and Publish Skills / build-and-publish (pull_request) Successful in 4s
582b96f479
Merge branch 'development' into development_service_mail
All checks were successful
Build and Publish Skills / build-and-publish (pull_request) Successful in 3s
6f77c7c1f7
mahmoud merged commit 0dbcceafbe into development 2026-04-29 13:16:58 +00:00
mahmoud deleted branch development_service_mail 2026-04-29 13:17:01 +00:00
Sign in to join this conversation.
No reviewers
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_skills!168
No description provided.