service_shrimp.nu — hero_shrimp lifecycle module #155

Closed
opened 2026-04-28 09:35:11 +00:00 by mahmoud · 5 comments
Owner

Add service_shrimp.nu per the tracker in #75. Module exposes install | start [--reset] | stop | status for the hero_shrimp stack.

Scope

  • Module file: tools/modules/services/service_shrimp.nu
  • Follow the standard pattern documented in the nu_service and nu_service_use skills.
  • Template to copy from: service_codescalers.nu — user-level Rust multi-binary that selfstarts via hero_proc; same shape as the hero_shrimp manager.
  • Source repo: hero_shrimp.

Service-specific notes

  • Pure Rust workspace; build via cargo build --release.
  • Four binaries to install to ~/hero/bin/: hero_shrimp, hero_shrimp_server, hero_shrimp_cli, hero_shrimp_ui (per the repo's buildenv.sh::BINARIES).
  • hero_shrimp is the lifecycle manager — it registers and starts hero_shrimp_server / hero_shrimp_ui via the hero_proc_service_selfstart pattern.
  • User-level service. No privileged ports, no --root.
  • Sockets bind under ~/hero/var/sockets/hero_shrimp/ (rpc.sock, admin.sock, ui.sock) — already canonical.
  • SQLite database under $SHRIMP_DATA_DIR (default ~/hero/var/data/hero_shrimp/).
  • At least one LLM provider key must be present in env or $SHRIMP_HOME/secrets.env: OPENROUTER_API_KEYS is the bundled default; OPENAI_API_KEYS, ANTHROPIC_API_KEYS, GROQ_API_KEYS, SAMBANOVA_API_KEYS are also honoured. Daemon boots without one but the first chat fails with "no providers configured".
  • Optional config: shrimp.yml (channels, models, backends) — auto-discovered, with a compiled-in default. The nu module shouldn't generate this — let users opt in.
  • Reference systemd unit at hero_shrimp/deploy/shrimp-daemon.service shows the lifecycle shape to mirror.

Acceptance criteria

  1. use services/mod.nu * makes service_shrimp available.
  2. On a target host:
    • service_shrimp install clones the repo, runs the appropriate build, and copies binaries to ~/hero/bin/.
    • service_shrimp start [--reset] registers with hero_proc and becomes healthy.
    • service_shrimp status reports the state.
    • service_shrimp stop cleanly unregisters.
  3. The start output prints sockets / UI URL / a short test plan, per the nu_service_use skill.

References

  • Parent tracker: #75
  • Pattern skills: nu_service, nu_service_use
  • Self-start pattern: hero_proc_service_selfstart
Add `service_shrimp.nu` per the tracker in #75. Module exposes `install | start [--reset] | stop | status` for the `hero_shrimp` stack. ## Scope - Module file: `tools/modules/services/service_shrimp.nu` - Follow the standard pattern documented in the [`nu_service`](../../src/branch/development/claude/skills/nu_service/SKILL.md) and [`nu_service_use`](../../src/branch/development/claude/skills/nu_service_use/SKILL.md) skills. - Template to copy from: `service_codescalers.nu` — user-level Rust multi-binary that selfstarts via hero_proc; same shape as the hero_shrimp manager. - Source repo: [`hero_shrimp`](https://forge.ourworld.tf/lhumina_code/hero_shrimp). ## Service-specific notes - Pure Rust workspace; build via `cargo build --release`. - Four binaries to install to `~/hero/bin/`: `hero_shrimp`, `hero_shrimp_server`, `hero_shrimp_cli`, `hero_shrimp_ui` (per the repo's `buildenv.sh::BINARIES`). - `hero_shrimp` is the lifecycle manager — it registers and starts `hero_shrimp_server` / `hero_shrimp_ui` via the [`hero_proc_service_selfstart`](../../src/branch/development/claude/skills/hero_proc_service_selfstart/SKILL.md) pattern. - **User-level** service. No privileged ports, no `--root`. - Sockets bind under `~/hero/var/sockets/hero_shrimp/` (`rpc.sock`, `admin.sock`, `ui.sock`) — already canonical. - SQLite database under `$SHRIMP_DATA_DIR` (default `~/hero/var/data/hero_shrimp/`). - At least one LLM provider key must be present in env or `$SHRIMP_HOME/secrets.env`: `OPENROUTER_API_KEYS` is the bundled default; `OPENAI_API_KEYS`, `ANTHROPIC_API_KEYS`, `GROQ_API_KEYS`, `SAMBANOVA_API_KEYS` are also honoured. Daemon boots without one but the first chat fails with "no providers configured". - Optional config: `shrimp.yml` (channels, models, backends) — auto-discovered, with a compiled-in default. The nu module shouldn't generate this — let users opt in. - Reference systemd unit at `hero_shrimp/deploy/shrimp-daemon.service` shows the lifecycle shape to mirror. ## Acceptance criteria 1. `use services/mod.nu *` makes `service_shrimp` available. 2. On a target host: - `service_shrimp install` clones the repo, runs the appropriate build, and copies binaries to `~/hero/bin/`. - `service_shrimp start [--reset]` registers with hero_proc and becomes healthy. - `service_shrimp status` reports the state. - `service_shrimp stop` cleanly unregisters. 3. The `start` output prints sockets / UI URL / a short test plan, per the `nu_service_use` skill. ## References - Parent tracker: #75 - Pattern skills: `nu_service`, `nu_service_use` - Self-start pattern: `hero_proc_service_selfstart`
mahmoud self-assigned this 2026-04-28 09:35:11 +00:00
mahmoud changed title from service_shrimp.nu — hero_shrimp (Bun/TS runtime) lifecycle module to service_shrimp.nu — hero_shrimp lifecycle module 2026-04-28 09:54:02 +00:00
mahmoud removed their assignment 2026-04-28 10:04:10 +00:00
Member

Implementation Spec for Issue #155

Objective

Add a new Nushell lifecycle module service_shrimp.nu to tools/modules/services/ so the Hero shell exposes service_shrimp install | start [--reset] | stop | status for the hero_shrimp stack. The module follows the canonical service_codescalers.nu shape (Rust workspace, multi-binary, registered with hero_proc as a single service whose CLI binary hero_shrimp self-registers hero_shrimp_server and hero_shrimp_ui actions). The module must NOT support --root (per the issue: hero_shrimp is user-level only, no privileged ports), must NOT generate shrimp.yml (auto-discovered, has compiled-in default), and must forward LLM provider keys from the invoking shell into the action env so the daemon and any chat call have credentials at hand. Once registered, the module exits with a printed summary block (sockets, UI URL via hero_router, log tail commands) so a downstream agent can drive it per nu_service_use.

Requirements

  • Module file at tools/modules/services/service_shrimp.nu, exporting install, start, stop, status.
  • install clones lhumina_code/hero_shrimp, runs cargo build for the four named binaries, and copies them to ~/hero/bin/.
  • start [--reset] [--update] is idempotent: ensures binaries, drops any prior registration, registers two actions (hero_shrimp_server, hero_shrimp_ui) and the hero_shrimp service with hero_proc, then starts.
  • start prints a summary with the rpc/admin/ui sockets, the hero_router URL, model-key status, and a short test plan (proc service status, proc logs tail).
  • stop cleanly drops the service and both actions.
  • status prints the hero_proc service record.
  • Diverge from service_codescalers.nu by removing --root plumbing and the multi-instance machinery — hero_shrimp is single-instance, user-level.
  • Forward OPENROUTER_API_KEYS, OPENAI_API_KEYS, ANTHROPIC_API_KEYS, GROQ_API_KEYS, SAMBANOVA_API_KEYS, SHRIMP_HOME, SHRIMP_DATA_DIR from invoking env into the server action env when set.
  • Non-fatal preflight warning if zero LLM provider keys are set (daemon boots, but the first chat fails). Mirrors svx_check_api_keys from service_aibroker.nu.
  • Add export use service_shrimp.nu to tools/modules/services/mod.nu.

Files to Modify/Create

  • tools/modules/services/service_shrimp.nu — NEW. The lifecycle module. Copy of service_codescalers.nu, edited per steps below.
  • tools/modules/services/mod.nu — MODIFIED. Add the export use service_shrimp.nu line.

Implementation Plan

Step 1: Create the module file as a stripped-down copy of service_codescalers.nu

Files: tools/modules/services/service_shrimp.nu

  • Start from a verbatim copy of service_codescalers.nu.
  • Replace global identifiers: hero_codescalershero_shrimp, service_codescalersservice_shrimp.
  • Drop HERO_CODESCALERS_DATA_DIR / HERO_CODESCALERS_SOCK_NAME. hero_shrimp uses SHRIMP_DATA_DIR and the canonical socket dir $HERO_SOCKET_DIR/hero_shrimp/ already.
  • Update top-of-file constants:
    • SVX_SERVICE_NAME = "hero_shrimp"
    • SVX_FORGE_LOC = "lhumina_code/hero_shrimp"
    • SVX_BINARIES = ["hero_shrimp" "hero_shrimp_server" "hero_shrimp_cli" "hero_shrimp_ui"]
    • SVX_ACTIONS = ["hero_shrimp_server" "hero_shrimp_ui"] (CLI and hero_shrimp_cli ship but are not actions).
    • SVX_DESCRIPTION = "Hero Shrimp — LLM agent runtime with admin UI".
  • Replace top-of-file docstring with a description of hero_shrimp: role, three sockets, SQLite data dir, LLM-key precondition, note that --root is intentionally absent.

Dependencies: none

Step 2: Strip multi-instance and --root machinery

Files: tools/modules/services/service_shrimp.nu

  • Delete instance helpers (svx_svc_name, svx_sock_dir, svx_server_action_name, svx_ui_action_name, svx_actions, svx_data_dir).
  • Replace action-builder signatures: drop root: bool, instance: int params.
  • Remove --root(-r) and --instance from every public command (install, start, stop, status). Do NOT include codescalers' reset subcommand — out of scope.
  • Pass false everywhere $root was passed in lib.nu calls (svc_bin, svc_sock_base, svc_install, svc_drop_registration, svc_require_binary, svc_stop_service, svc_service_status, svc_start_preflight, proc action set --root=false, proc service set --root=false, proc service start --root=false).
  • Strip the if not $root { error make ... } block and any svc_require_sudo from start.

Dependencies: Step 1

Step 3: Wire the LLM-provider key preflight + env forwarding

Files: tools/modules/services/service_shrimp.nu

  • Add helper modeled on svx_check_api_keys from service_aibroker.nu:
const SVX_PROVIDER_KEYS = [
    "OPENROUTER_API_KEYS"
    "OPENAI_API_KEYS"
    "ANTHROPIC_API_KEYS"
    "GROQ_API_KEYS"
    "SAMBANOVA_API_KEYS"
]

def svx_check_provider_keys [] {
    let present = ($SVX_PROVIDER_KEYS | where {|k| ($env | get -o $k | default "") | is-not-empty })
    if ($present | is-empty) {
        print "warn: no LLM provider keys found in env (OPENROUTER_API_KEYS / OPENAI_API_KEYS /"
        print "      ANTHROPIC_API_KEYS / GROQ_API_KEYS / SAMBANOVA_API_KEYS)."
        print "      hero_shrimp will start, but the first chat will fail with"
        print "      'no providers configured' until at least one is set in env or"
        print "      in $SHRIMP_HOME/secrets.env."
    } else {
        print $"  ok: LLM provider keys present: ($present | str join ', ')"
    }
}
  • In svx_server_action, build env from {RUST_LOG: "info,hero_shrimp_server=info"} and conditionally insert any of SVX_PROVIDER_KEYS plus SHRIMP_HOME and SHRIMP_DATA_DIR that are set. Use mut envs + for var in [...] pattern:
mut envs = {RUST_LOG: "info,hero_shrimp_server=info"}
for var in ($SVX_PROVIDER_KEYS ++ ["SHRIMP_HOME" "SHRIMP_DATA_DIR"]) {
    let val = ($env | get -o $var | default "")
    if ($val | is-not-empty) {
        $envs = ($envs | insert $var $val)
    }
}
  • Server action: is_process: true, svc_server_timing spread, kill_other.socket = [rpc.sock, admin.sock], single health_checks entry against rpc.sock with svc_server_health_policy.
  • UI action: env {RUST_LOG: "info"}, kill_other.socket = [ui.sock], health check on ui.sock with svc_ui_health_policy.
  • Call svx_check_provider_keys in start immediately after svc_start_preflight returns.

Dependencies: Step 2

Step 4: Rewrite the start summary block

Files: tools/modules/services/service_shrimp.nu

  • Print:
    • rpc sock: $sock_base/hero_shrimp/rpc.sock
    • admin sock: $sock_base/hero_shrimp/admin.sock
    • ui sock: $sock_base/hero_shrimp/ui.sock
    • ui url: http://<host>:9988/hero_shrimp/ui/ (via hero_router)
    • data dir: $SHRIMP_DATA_DIR (default ~/hero/var/data/hero_shrimp/)
  • Drop the instance line and the flag variable.
  • Keep the proc logs tail hero_shrimp_server --lines 30 startup-log fallback verbatim.
  • Final command list: proc service status hero_shrimp, proc logs tail hero_shrimp_server, proc logs tail hero_shrimp_ui, proc job list --service hero_shrimp.

Dependencies: Step 3

Step 5: Register the module in services/mod.nu

Files: tools/modules/services/mod.nu

  • Add export use service_shrimp.nu next to the other lifecycle exports (append after service_claude.nu to follow existing append pattern).

Dependencies: Step 1 (file must exist before being exported)

Step 6: Smoke-check the module can be parsed

Files: none modified

  • Run use services/mod.nu * and service_shrimp --help from a Hero shell. Confirm parse.
  • Optional: service_shrimp install, service_shrimp start --reset, hit the ui url per nu_service_use.

Dependencies: Step 5

Acceptance Criteria

  • use services/mod.nu * makes service_shrimp available as a subcommand group with install, start, stop, status.
  • service_shrimp install clones lhumina_code/hero_shrimp, builds the four binaries, and copies them to ~/hero/bin/.
  • service_shrimp start [--reset] registers hero_shrimp_server and hero_shrimp_ui actions plus the hero_shrimp service with hero_proc and reaches a healthy state.
  • service_shrimp status reports state via proc service status.
  • service_shrimp stop cleanly drops the service and both actions.
  • start output prints sockets, hero_router UI URL, and the test-plan command list per nu_service_use.
  • If no LLM provider keys are present in env, start prints a non-fatal warning.

Notes

  • Diverges from service_codescalers.nu: four binaries (only two are hero_proc actions), no --root, no --instance, no reset subcommand. Three server-bound sockets (rpc.sock, admin.sock, ui.sock); UI action owns ui.sock. admin.sock is intentionally not health-checked (no canonical endpoint).
  • Adds an LLM-key preflight covering five env vars (OPENROUTER_API_KEYS is plural — daemon expects this exact name).
  • Do NOT generate shrimp.yml. Compiled-in default + optional auto-discovery handles channels/models/backends.
  • Forward SHRIMP_DATA_DIR and SHRIMP_HOME from env without injecting defaults — let the daemon fall back.
  • hero_shrimp (orchestrator CLI) and hero_shrimp_cli (operator tool) are in SVX_BINARIES but NOT in SVX_ACTIONS — same split as hero_codescalers and hero_aibroker_services.
  • Default to debug build (matches every other lifecycle module). --release honoured when passed.
  • --update flag inherited from service_codescalers.nu's svc_install wrapper — keep it on both install and start.
## Implementation Spec for Issue #155 ### Objective Add a new Nushell lifecycle module `service_shrimp.nu` to `tools/modules/services/` so the Hero shell exposes `service_shrimp install | start [--reset] | stop | status` for the `hero_shrimp` stack. The module follows the canonical `service_codescalers.nu` shape (Rust workspace, multi-binary, registered with `hero_proc` as a single service whose CLI binary `hero_shrimp` self-registers `hero_shrimp_server` and `hero_shrimp_ui` actions). The module must NOT support `--root` (per the issue: hero_shrimp is user-level only, no privileged ports), must NOT generate `shrimp.yml` (auto-discovered, has compiled-in default), and must forward LLM provider keys from the invoking shell into the action env so the daemon and any chat call have credentials at hand. Once registered, the module exits with a printed summary block (sockets, UI URL via hero_router, log tail commands) so a downstream agent can drive it per `nu_service_use`. ### Requirements - Module file at `tools/modules/services/service_shrimp.nu`, exporting `install`, `start`, `stop`, `status`. - `install` clones `lhumina_code/hero_shrimp`, runs `cargo build` for the four named binaries, and copies them to `~/hero/bin/`. - `start [--reset] [--update]` is idempotent: ensures binaries, drops any prior registration, registers two actions (`hero_shrimp_server`, `hero_shrimp_ui`) and the `hero_shrimp` service with hero_proc, then starts. - `start` prints a summary with the rpc/admin/ui sockets, the hero_router URL, model-key status, and a short test plan (`proc service status`, `proc logs tail`). - `stop` cleanly drops the service and both actions. - `status` prints the hero_proc service record. - Diverge from `service_codescalers.nu` by removing `--root` plumbing and the multi-instance machinery — hero_shrimp is single-instance, user-level. - Forward `OPENROUTER_API_KEYS`, `OPENAI_API_KEYS`, `ANTHROPIC_API_KEYS`, `GROQ_API_KEYS`, `SAMBANOVA_API_KEYS`, `SHRIMP_HOME`, `SHRIMP_DATA_DIR` from invoking env into the server action env when set. - Non-fatal preflight warning if zero LLM provider keys are set (daemon boots, but the first chat fails). Mirrors `svx_check_api_keys` from `service_aibroker.nu`. - Add `export use service_shrimp.nu` to `tools/modules/services/mod.nu`. ### Files to Modify/Create - `tools/modules/services/service_shrimp.nu` — NEW. The lifecycle module. Copy of `service_codescalers.nu`, edited per steps below. - `tools/modules/services/mod.nu` — MODIFIED. Add the `export use service_shrimp.nu` line. ### Implementation Plan #### Step 1: Create the module file as a stripped-down copy of service_codescalers.nu Files: `tools/modules/services/service_shrimp.nu` - Start from a verbatim copy of `service_codescalers.nu`. - Replace global identifiers: `hero_codescalers` → `hero_shrimp`, `service_codescalers` → `service_shrimp`. - Drop `HERO_CODESCALERS_DATA_DIR` / `HERO_CODESCALERS_SOCK_NAME`. hero_shrimp uses `SHRIMP_DATA_DIR` and the canonical socket dir `$HERO_SOCKET_DIR/hero_shrimp/` already. - Update top-of-file constants: - `SVX_SERVICE_NAME = "hero_shrimp"` - `SVX_FORGE_LOC = "lhumina_code/hero_shrimp"` - `SVX_BINARIES = ["hero_shrimp" "hero_shrimp_server" "hero_shrimp_cli" "hero_shrimp_ui"]` - `SVX_ACTIONS = ["hero_shrimp_server" "hero_shrimp_ui"]` (CLI and `hero_shrimp_cli` ship but are not actions). - `SVX_DESCRIPTION = "Hero Shrimp — LLM agent runtime with admin UI"`. - Replace top-of-file docstring with a description of `hero_shrimp`: role, three sockets, SQLite data dir, LLM-key precondition, note that `--root` is intentionally absent. Dependencies: none #### Step 2: Strip multi-instance and --root machinery Files: `tools/modules/services/service_shrimp.nu` - Delete instance helpers (`svx_svc_name`, `svx_sock_dir`, `svx_server_action_name`, `svx_ui_action_name`, `svx_actions`, `svx_data_dir`). - Replace action-builder signatures: drop `root: bool, instance: int` params. - Remove `--root(-r)` and `--instance` from every public command (`install`, `start`, `stop`, `status`). Do NOT include codescalers' `reset` subcommand — out of scope. - Pass `false` everywhere `$root` was passed in `lib.nu` calls (`svc_bin`, `svc_sock_base`, `svc_install`, `svc_drop_registration`, `svc_require_binary`, `svc_stop_service`, `svc_service_status`, `svc_start_preflight`, `proc action set --root=false`, `proc service set --root=false`, `proc service start --root=false`). - Strip the `if not $root { error make ... }` block and any `svc_require_sudo` from `start`. Dependencies: Step 1 #### Step 3: Wire the LLM-provider key preflight + env forwarding Files: `tools/modules/services/service_shrimp.nu` - Add helper modeled on `svx_check_api_keys` from `service_aibroker.nu`: ```nushell const SVX_PROVIDER_KEYS = [ "OPENROUTER_API_KEYS" "OPENAI_API_KEYS" "ANTHROPIC_API_KEYS" "GROQ_API_KEYS" "SAMBANOVA_API_KEYS" ] def svx_check_provider_keys [] { let present = ($SVX_PROVIDER_KEYS | where {|k| ($env | get -o $k | default "") | is-not-empty }) if ($present | is-empty) { print "warn: no LLM provider keys found in env (OPENROUTER_API_KEYS / OPENAI_API_KEYS /" print " ANTHROPIC_API_KEYS / GROQ_API_KEYS / SAMBANOVA_API_KEYS)." print " hero_shrimp will start, but the first chat will fail with" print " 'no providers configured' until at least one is set in env or" print " in $SHRIMP_HOME/secrets.env." } else { print $" ok: LLM provider keys present: ($present | str join ', ')" } } ``` - In `svx_server_action`, build env from `{RUST_LOG: "info,hero_shrimp_server=info"}` and conditionally insert any of `SVX_PROVIDER_KEYS` plus `SHRIMP_HOME` and `SHRIMP_DATA_DIR` that are set. Use `mut envs` + `for var in [...]` pattern: ```nushell mut envs = {RUST_LOG: "info,hero_shrimp_server=info"} for var in ($SVX_PROVIDER_KEYS ++ ["SHRIMP_HOME" "SHRIMP_DATA_DIR"]) { let val = ($env | get -o $var | default "") if ($val | is-not-empty) { $envs = ($envs | insert $var $val) } } ``` - Server action: `is_process: true`, `svc_server_timing` spread, `kill_other.socket = [rpc.sock, admin.sock]`, single `health_checks` entry against `rpc.sock` with `svc_server_health_policy`. - UI action: env `{RUST_LOG: "info"}`, `kill_other.socket = [ui.sock]`, health check on `ui.sock` with `svc_ui_health_policy`. - Call `svx_check_provider_keys` in `start` immediately after `svc_start_preflight` returns. Dependencies: Step 2 #### Step 4: Rewrite the start summary block Files: `tools/modules/services/service_shrimp.nu` - Print: - `rpc sock: $sock_base/hero_shrimp/rpc.sock` - `admin sock: $sock_base/hero_shrimp/admin.sock` - `ui sock: $sock_base/hero_shrimp/ui.sock` - `ui url: http://<host>:9988/hero_shrimp/ui/ (via hero_router)` - `data dir: $SHRIMP_DATA_DIR (default ~/hero/var/data/hero_shrimp/)` - Drop the `instance` line and the `flag` variable. - Keep the `proc logs tail hero_shrimp_server --lines 30` startup-log fallback verbatim. - Final command list: `proc service status hero_shrimp`, `proc logs tail hero_shrimp_server`, `proc logs tail hero_shrimp_ui`, `proc job list --service hero_shrimp`. Dependencies: Step 3 #### Step 5: Register the module in services/mod.nu Files: `tools/modules/services/mod.nu` - Add `export use service_shrimp.nu` next to the other lifecycle exports (append after `service_claude.nu` to follow existing append pattern). Dependencies: Step 1 (file must exist before being exported) #### Step 6: Smoke-check the module can be parsed Files: none modified - Run `use services/mod.nu *` and `service_shrimp --help` from a Hero shell. Confirm parse. - Optional: `service_shrimp install`, `service_shrimp start --reset`, hit the `ui url` per `nu_service_use`. Dependencies: Step 5 ### Acceptance Criteria - [ ] `use services/mod.nu *` makes `service_shrimp` available as a subcommand group with `install`, `start`, `stop`, `status`. - [ ] `service_shrimp install` clones `lhumina_code/hero_shrimp`, builds the four binaries, and copies them to `~/hero/bin/`. - [ ] `service_shrimp start [--reset]` registers `hero_shrimp_server` and `hero_shrimp_ui` actions plus the `hero_shrimp` service with hero_proc and reaches a healthy state. - [ ] `service_shrimp status` reports state via `proc service status`. - [ ] `service_shrimp stop` cleanly drops the service and both actions. - [ ] `start` output prints sockets, hero_router UI URL, and the test-plan command list per `nu_service_use`. - [ ] If no LLM provider keys are present in env, `start` prints a non-fatal warning. ### Notes - Diverges from `service_codescalers.nu`: four binaries (only two are hero_proc actions), no `--root`, no `--instance`, no `reset` subcommand. Three server-bound sockets (`rpc.sock`, `admin.sock`, `ui.sock`); UI action owns `ui.sock`. `admin.sock` is intentionally not health-checked (no canonical endpoint). - Adds an LLM-key preflight covering five env vars (`OPENROUTER_API_KEYS` is plural — daemon expects this exact name). - Do NOT generate `shrimp.yml`. Compiled-in default + optional auto-discovery handles channels/models/backends. - Forward `SHRIMP_DATA_DIR` and `SHRIMP_HOME` from env without injecting defaults — let the daemon fall back. - `hero_shrimp` (orchestrator CLI) and `hero_shrimp_cli` (operator tool) are in `SVX_BINARIES` but NOT in `SVX_ACTIONS` — same split as `hero_codescalers` and `hero_aibroker_services`. - Default to debug build (matches every other lifecycle module). `--release` honoured when passed. - `--update` flag inherited from `service_codescalers.nu`'s `svc_install` wrapper — keep it on both `install` and `start`.
Member

Smoke test results

Check Result
Module parses (use services/mod.nu *) ok
service_shrimp install help ok
service_shrimp start help ok
service_shrimp stop help ok
service_shrimp status help ok

Total: 5 / Passed: 5 / Failed: 0

All five checks passed. The module loads cleanly and exposes the required install | start | stop | status subcommands. start exposes --reset(-r), --update(-u), and --release; install exposes --update(-u) and --release; stop and status take no flags beyond --help. No --root or --instance flags are present on any subcommand.

## Smoke test results | Check | Result | |---|---| | Module parses (`use services/mod.nu *`) | ok | | `service_shrimp install` help | ok | | `service_shrimp start` help | ok | | `service_shrimp stop` help | ok | | `service_shrimp status` help | ok | Total: 5 / Passed: 5 / Failed: 0 All five checks passed. The module loads cleanly and exposes the required `install | start | stop | status` subcommands. `start` exposes `--reset(-r)`, `--update(-u)`, and `--release`; `install` exposes `--update(-u)` and `--release`; `stop` and `status` take no flags beyond `--help`. No `--root` or `--instance` flags are present on any subcommand.
Member

Implementation summary

Added service_shrimp.nu to tools/modules/services/ and registered it in services/mod.nu. The module follows the canonical lifecycle shape (matching service_codescalers.nu and service_aibroker.nu) but is single-instance and user-level — no --root, no --instance, no reset subcommand.

Files

  • NEW tools/modules/services/service_shrimp.nuinstall | start [--reset] [--update] [--release] | stop | status for the hero_shrimp stack.
  • MODIFIED tools/modules/services/mod.nu — added export use service_shrimp.nu.

Behaviour

  • install clones lhumina_code/hero_shrimp, runs cargo build, copies the four binaries (hero_shrimp, hero_shrimp_server, hero_shrimp_cli, hero_shrimp_ui) into ~/hero/bin/.
  • start registers two hero_proc actions (hero_shrimp_server, hero_shrimp_ui) plus the hero_shrimp service, then starts. Idempotent unless --reset is passed.
  • stop cleanly drops the service and both actions.
  • status reports state via proc service status.
  • LLM provider keys (OPENROUTER_API_KEYS, OPENAI_API_KEYS, ANTHROPIC_API_KEYS, GROQ_API_KEYS, SAMBANOVA_API_KEYS) plus SHRIMP_HOME and SHRIMP_DATA_DIR are forwarded from the invoking shell into the server action env when set. A non-fatal preflight prints a warning when none are present.
  • start summary block prints the three sockets (rpc.sock, admin.sock, ui.sock), the hero_router UI URL, the data dir, and a short test plan (proc service status, proc logs tail, proc job list).
  • admin.sock is intentionally not health-checked (no canonical endpoint); server health checks rpc.sock, UI action health checks ui.sock.
  • No shrimp.yml is generated — the daemon's compiled-in default plus optional auto-discovery handles config.

Test results

Parse-and-export smoke check (5/5 passed):

Check Result
use services/mod.nu * parses ok
service_shrimp install help ok
service_shrimp start help ok
service_shrimp stop help ok
service_shrimp status help ok

Subcommands expose the expected flags: start has --reset(-r), --update(-u), --release; install has --update(-u), --release; stop and status take no flags. No --root or --instance anywhere.

End-to-end install/start/stop on a target host is left to the operator — it requires the lhumina_code/hero_shrimp source to be reachable and a hero_proc daemon running.

## Implementation summary Added `service_shrimp.nu` to `tools/modules/services/` and registered it in `services/mod.nu`. The module follows the canonical lifecycle shape (matching `service_codescalers.nu` and `service_aibroker.nu`) but is single-instance and user-level — no `--root`, no `--instance`, no `reset` subcommand. ### Files - **NEW** `tools/modules/services/service_shrimp.nu` — `install | start [--reset] [--update] [--release] | stop | status` for the hero_shrimp stack. - **MODIFIED** `tools/modules/services/mod.nu` — added `export use service_shrimp.nu`. ### Behaviour - `install` clones `lhumina_code/hero_shrimp`, runs `cargo build`, copies the four binaries (`hero_shrimp`, `hero_shrimp_server`, `hero_shrimp_cli`, `hero_shrimp_ui`) into `~/hero/bin/`. - `start` registers two hero_proc actions (`hero_shrimp_server`, `hero_shrimp_ui`) plus the `hero_shrimp` service, then starts. Idempotent unless `--reset` is passed. - `stop` cleanly drops the service and both actions. - `status` reports state via `proc service status`. - LLM provider keys (`OPENROUTER_API_KEYS`, `OPENAI_API_KEYS`, `ANTHROPIC_API_KEYS`, `GROQ_API_KEYS`, `SAMBANOVA_API_KEYS`) plus `SHRIMP_HOME` and `SHRIMP_DATA_DIR` are forwarded from the invoking shell into the server action env when set. A non-fatal preflight prints a warning when none are present. - `start` summary block prints the three sockets (`rpc.sock`, `admin.sock`, `ui.sock`), the hero_router UI URL, the data dir, and a short test plan (`proc service status`, `proc logs tail`, `proc job list`). - `admin.sock` is intentionally not health-checked (no canonical endpoint); server health checks `rpc.sock`, UI action health checks `ui.sock`. - No `shrimp.yml` is generated — the daemon's compiled-in default plus optional auto-discovery handles config. ### Test results Parse-and-export smoke check (5/5 passed): | Check | Result | |---|---| | `use services/mod.nu *` parses | ok | | `service_shrimp install` help | ok | | `service_shrimp start` help | ok | | `service_shrimp stop` help | ok | | `service_shrimp status` help | ok | Subcommands expose the expected flags: `start` has `--reset(-r)`, `--update(-u)`, `--release`; `install` has `--update(-u)`, `--release`; `stop` and `status` take no flags. No `--root` or `--instance` anywhere. End-to-end install/start/stop on a target host is left to the operator — it requires the `lhumina_code/hero_shrimp` source to be reachable and a hero_proc daemon running.
Member

Pull request opened: #170

This PR implements the changes discussed in this issue.

Pull request opened: https://forge.ourworld.tf/lhumina_code/hero_skills/pulls/170 This PR implements the changes discussed in this issue.
Member

End-to-end validation on host

Ran the full lifecycle against a live hero_proc (already supervising 22 services).

install

service_shrimp install
  • Cloned lhumina_code/hero_shrimp to ~/hero/code0/hero_shrimp/.
  • cargo build (debug) finished in 1m 12s.
  • 4 binaries copied to ~/hero/bin/: hero_shrimp (105 MB), hero_shrimp_server (509 MB), hero_shrimp_cli (59 MB), hero_shrimp_ui (63 MB).

start

service_shrimp start
  • LLM-key preflight printed the expected non-fatal warning (no provider keys in env).
  • Registered hero_shrimp_server and hero_shrimp_ui actions plus the hero_shrimp service with hero_proc.
  • Service booted: schema migrations 0→1→2→3 applied, JSON-RPC listening on rpc.sock, UI listening on ui.sock and proxying to the server.
  • Summary block printed sockets, hero_router URL, data dir, and the test plan as required.

status

service_shrimp status
Field Value
name hero_shrimp
state running
pid 1827077
current_run_id 42
restarts 0

UI reachable end-to-end:

  • direct (curl --unix-socket .../ui.sock http://localhost/) → 200
  • via hero_router (http://localhost:9988/hero_shrimp/ui/) → 308 redirect (canonical trailing-slash redirect — proxy works)

stop

service_shrimp stop
  • Service and both actions cleanly unregistered from hero_proc.
  • proc service list no longer shows hero_shrimp.
  • A stale ui.sock file remains in ~/hero/var/sockets/hero_shrimp/ — expected; the UI action's kill_other clears it on next startup before bind, which is the standard pattern across all sibling lifecycle modules.

All four acceptance criteria from the issue pass.

## End-to-end validation on host Ran the full lifecycle against a live `hero_proc` (already supervising 22 services). ### install ``` service_shrimp install ``` - Cloned `lhumina_code/hero_shrimp` to `~/hero/code0/hero_shrimp/`. - `cargo build` (debug) finished in 1m 12s. - 4 binaries copied to `~/hero/bin/`: `hero_shrimp` (105 MB), `hero_shrimp_server` (509 MB), `hero_shrimp_cli` (59 MB), `hero_shrimp_ui` (63 MB). ### start ``` service_shrimp start ``` - LLM-key preflight printed the expected non-fatal warning (no provider keys in env). - Registered `hero_shrimp_server` and `hero_shrimp_ui` actions plus the `hero_shrimp` service with hero_proc. - Service booted: schema migrations 0→1→2→3 applied, JSON-RPC listening on `rpc.sock`, UI listening on `ui.sock` and proxying to the server. - Summary block printed sockets, hero_router URL, data dir, and the test plan as required. ### status ``` service_shrimp status ``` | Field | Value | |---|---| | name | hero_shrimp | | state | running | | pid | 1827077 | | current_run_id | 42 | | restarts | 0 | UI reachable end-to-end: - direct (`curl --unix-socket .../ui.sock http://localhost/`) → `200` - via hero_router (`http://localhost:9988/hero_shrimp/ui/`) → `308` redirect (canonical trailing-slash redirect — proxy works) ### stop ``` service_shrimp stop ``` - Service and both actions cleanly unregistered from hero_proc. - `proc service list` no longer shows `hero_shrimp`. - A stale `ui.sock` file remains in `~/hero/var/sockets/hero_shrimp/` — expected; the UI action's `kill_other` clears it on next startup before bind, which is the standard pattern across all sibling lifecycle modules. All four acceptance criteria from the issue pass.
Sign in to join this conversation.
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#155
No description provided.