MOOS App Builder
Overview
Use this skill for user application development against the local MOOS-IvP checkout. Treat MOOS-IvP itself as the dependency and example source unless the user explicitly asks to patch core MOOS-IvP.
MOOS-IvP Checkout Resolution
When this skill needs a local MOOS-IvP checkout, resolve it in this order:
- Path explicitly provided by the user.
MOOS_IVP_ROOT from the shell environment.
- Active task workspace if it contains
ivp/src.
- Parent or sibling directories near the active task workspace.
- Common home locations such as
~/moos-ivp, ~/src/moos-ivp, ~/repos/moos-ivp, and ~/projects/moos-ivp.
- A bounded shallow home search for a directory named
moos-ivp, excluding noisy folders.
Validate a candidate by confirming ivp/src exists and scripts/GenMOOSApp_AppCasting is executable.
If no valid checkout is found and the task requires app source generation, build wiring, examples, headers, or libraries, stop and ask the user for the checkout path before editing code, generating build files, or using placeholder paths.
Core Rules
- Use
GenMOOSApp_AppCasting for new apps.
- If the project has
src/CMakeLists.txt, update it with ADD_SUBDIRECTORY(<app-dir>).
- If the project has no build skeleton, create the smallest project-level CMake needed for the new app and point it at the resolved
MOOS_IVP_ROOT.
- Keep MOOS communication boundaries clear:
OnNewMail() ingests mail, validates messages, and updates state through handleMail* helpers; Iterate() owns most business logic, recurring work, and state-derived publications.
- Keep config parsing in
OnStartUp(), using handleConfig* helpers for nontrivial values and AppCasting warnings for bad or unhandled config.
- Keep subscriptions centralized in
registerVariables() and call AppCastingMOOSApp::RegisterVariables() in AppCasting apps.
- Update
_Info.cpp as part of the app implementation: synopsis, example config, subscriptions, publications, and options must describe the real app.
- Preserve the generator-style metadata comment box at the top of source files and update
NAME, ORGN, FILE, and DATE to match the user project.
- Use short comments before non-obvious logic blocks; do not add comments that merely restate simple code.
- Reuse existing MOOS-IvP libraries and helpers before writing new parsing, geometry, contact, logic, or AppCasting support code.
- Use local style: MOOS variables are usually uppercase with underscores; mission config params are usually lowercase snake case; C++ members use
m_; helpers commonly use handleMail*, handleConfig*, post*, update*.
- Build and run
--help, --example, and --interface as binary smoke checks
before finishing when feasible. These prove the app starts and its
self-documentation is wired; they do not prove mission runtime config.
- During live validation, keep
pAntler in the foreground unless the task
explicitly requires persistent or concurrent execution. Use the shortest
timeout that proves the claim, capped at 30 seconds unless a stated
task-specific reason requires longer. After it stops, verify scoped processes
and selected ports are clear.
- Do not commit or present build directories/binaries as source changes unless the user's project already tracks generated artifacts.
Workflow
- Identify the app role and prefix.
p: process/control/monitoring app
u: utility or simulation-support app
uFld: shoreside field app
i: interface/driver app
- If the user did not specify a prefix, use
p for process/control/monitoring apps and u for utilities or simulation helpers.
- Generate the starting point.
- New app: run
$MOOS_IVP_ROOT/scripts/GenMOOSApp_AppCasting <Name> <prefix> "<Author>" from the project source directory.
- Inspect existing apps as references. Copy an existing app when the user explicitly asks or when it is obviously the nearest local-project base.
- Wire the build.
- Read
references/app-build.md before creating or repairing project-level CMake.
- Preserve existing project CMake style when present.
- Implement app behavior.
- Read
references/app-patterns.md for mail/config/iterate/AppCasting conventions.
- Store the latest relevant mail in state; keep expensive, repeated, or state-combining work in
Iterate(). Publish directly from OnNewMail() only for trivial acknowledgments or explicitly requested immediate reactions.
- Validate message type before using
GetDouble() or GetString().
- Update user-facing app metadata.
showSynopsis()
showExampleConfigAndExit()
showInterfaceAndExit()
- Use the smallest live environment that proves the app's runtime claims. A
focused app can use a single-community
pAntler configuration; add
moos-ivp-mission-builder only when the task owns broader mission topology,
routing, launchers, or controls—not merely for live app validation.
- Use
ProcessConfig = <AppName> with realistic AppTick and CommsTick.
- If only source was requested, an example
ProcessConfig in _Info.cpp is
enough. If a runnable sample mission was requested, include the
ProcessConfig and the pAntler or launcher context that actually starts
the app.
- Add the app to
pAntler or the mission launcher pattern only if the existing mission uses that style.
- Ensure the launcher can find the built app binary. For external projects,
prefer a minimal
pAntler validation mission with a launcher-local
PATH=<project>/bin:$PATH extension, or document the persistent shell
setup that puts the project bin/ on PATH.
- Validate.
- Configure/build the project or target when feasible.
- Run the generated binary with
--help, --example, and --interface as
smoke checks when those options are supported.
- If runtime config matters, validate through a normal
pAntler launch with
ProcessConfig = <AppName> rather than treating a direct binary run as
equivalent.
- If a mission was touched, launch only when the user asked for runtime validation or the change is risky enough to justify it.
Reference Use
- Read
references/app-build.md when the project build layout is missing, broken, or unfamiliar.
- Read
references/app-patterns.md before implementing nontrivial app logic.
- Read
references/app-examples.md when choosing a representative app to inspect in the resolved MOOS_IVP_ROOT.
Validation Checklist
- App has a project build entry.
- App links only the libraries it actually needs, plus
apputil for AppCasting and mbutil for common utilities.
OnNewMail() handles or deliberately ignores subscribed mail without warning on APPCAST_REQ.
registerVariables() lists every subscribed variable.
showInterfaceAndExit() matches actual subscriptions/publications.
- Build succeeds, or the blocker is reported with the exact missing dependency/error.
--help, --example, and --interface reflect the real app and do not
crash when supported.
- Runtime config, when relevant, is verified through
pAntler with
ProcessConfig = <AppName>, not by direct app-by-path execution alone.
- For clean-host or relocatable claims, run
<skill-dir>/scripts/check_portable_paths.sh <project-dir>, resolving
<skill-dir> as the directory containing this SKILL.md, and include a
clean build with a caller-supplied non-default MOOS_IVP_ROOT.
1---2name: moos-app-builder3description: Build or modify user-owned MOOS apps outside the core MOOS-IvP source tree: C++ app generation, project build wiring, MOOS mail/config/iterate logic, app help/interface text, and app-specific ProcessConfig examples.4---56# MOOS App Builder78## Overview910Use this skill for user application development against the local MOOS-IvP checkout. Treat MOOS-IvP itself as the dependency and example source unless the user explicitly asks to patch core MOOS-IvP.1112## MOOS-IvP Checkout Resolution1314When this skill needs a local MOOS-IvP checkout, resolve it in this order:15161. Path explicitly provided by the user.172. `MOOS_IVP_ROOT` from the shell environment.183. Active task workspace if it contains `ivp/src`.194. Parent or sibling directories near the active task workspace.205. Common home locations such as `~/moos-ivp`, `~/src/moos-ivp`, `~/repos/moos-ivp`, and `~/projects/moos-ivp`.216. A bounded shallow home search for a directory named `moos-ivp`, excluding noisy folders.2223Validate a candidate by confirming `ivp/src` exists and `scripts/GenMOOSApp_AppCasting` is executable.2425If no valid checkout is found and the task requires app source generation, build wiring, examples, headers, or libraries, stop and ask the user for the checkout path before editing code, generating build files, or using placeholder paths.2627## Core Rules2829- Use `GenMOOSApp_AppCasting` for new apps.30- If the project has `src/CMakeLists.txt`, update it with `ADD_SUBDIRECTORY(<app-dir>)`.31- If the project has no build skeleton, create the smallest project-level CMake needed for the new app and point it at the resolved `MOOS_IVP_ROOT`.32- Keep MOOS communication boundaries clear: `OnNewMail()` ingests mail, validates messages, and updates state through `handleMail*` helpers; `Iterate()` owns most business logic, recurring work, and state-derived publications.33- Keep config parsing in `OnStartUp()`, using `handleConfig*` helpers for nontrivial values and AppCasting warnings for bad or unhandled config.34- Keep subscriptions centralized in `registerVariables()` and call `AppCastingMOOSApp::RegisterVariables()` in AppCasting apps.35- Update `_Info.cpp` as part of the app implementation: synopsis, example config, subscriptions, publications, and options must describe the real app.36- Preserve the generator-style metadata comment box at the top of source files and update `NAME`, `ORGN`, `FILE`, and `DATE` to match the user project.37- Use short comments before non-obvious logic blocks; do not add comments that merely restate simple code.38- Reuse existing MOOS-IvP libraries and helpers before writing new parsing, geometry, contact, logic, or AppCasting support code.39- Use local style: MOOS variables are usually uppercase with underscores; mission config params are usually lowercase snake case; C++ members use `m_`; helpers commonly use `handleMail*`, `handleConfig*`, `post*`, `update*`.40- Build and run `--help`, `--example`, and `--interface` as binary smoke checks41 before finishing when feasible. These prove the app starts and its42 self-documentation is wired; they do not prove mission runtime config.43- During live validation, keep `pAntler` in the foreground unless the task44 explicitly requires persistent or concurrent execution. Use the shortest45 timeout that proves the claim, capped at 30 seconds unless a stated46 task-specific reason requires longer. After it stops, verify scoped processes47 and selected ports are clear.48- Do not commit or present build directories/binaries as source changes unless the user's project already tracks generated artifacts.4950## Workflow51521. Identify the app role and prefix.53 - `p`: process/control/monitoring app54 - `u`: utility or simulation-support app55 - `uFld`: shoreside field app56 - `i`: interface/driver app57 - If the user did not specify a prefix, use `p` for process/control/monitoring apps and `u` for utilities or simulation helpers.582. Generate the starting point.59 - New app: run `$MOOS_IVP_ROOT/scripts/GenMOOSApp_AppCasting <Name> <prefix> "<Author>"` from the project source directory.60 - Inspect existing apps as references. Copy an existing app when the user explicitly asks or when it is obviously the nearest local-project base.613. Wire the build.62 - Read `references/app-build.md` before creating or repairing project-level CMake.63 - Preserve existing project CMake style when present.644. Implement app behavior.65 - Read `references/app-patterns.md` for mail/config/iterate/AppCasting conventions.66 - Store the latest relevant mail in state; keep expensive, repeated, or state-combining work in `Iterate()`. Publish directly from `OnNewMail()` only for trivial acknowledgments or explicitly requested immediate reactions.67 - Validate message type before using `GetDouble()` or `GetString()`.685. Update user-facing app metadata.69 - `showSynopsis()`70 - `showExampleConfigAndExit()`71 - `showInterfaceAndExit()`726. Use the smallest live environment that proves the app's runtime claims. A73 focused app can use a single-community `pAntler` configuration; add74 `moos-ivp-mission-builder` only when the task owns broader mission topology,75 routing, launchers, or controls—not merely for live app validation.76 - Use `ProcessConfig = <AppName>` with realistic `AppTick` and `CommsTick`.77 - If only source was requested, an example `ProcessConfig` in `_Info.cpp` is78 enough. If a runnable sample mission was requested, include the79 `ProcessConfig` and the `pAntler` or launcher context that actually starts80 the app.81 - Add the app to `pAntler` or the mission launcher pattern only if the existing mission uses that style.82 - Ensure the launcher can find the built app binary. For external projects,83 prefer a minimal `pAntler` validation mission with a launcher-local84 `PATH=<project>/bin:$PATH` extension, or document the persistent shell85 setup that puts the project `bin/` on `PATH`.867. Validate.87 - Configure/build the project or target when feasible.88 - Run the generated binary with `--help`, `--example`, and `--interface` as89 smoke checks when those options are supported.90 - If runtime config matters, validate through a normal `pAntler` launch with91 `ProcessConfig = <AppName>` rather than treating a direct binary run as92 equivalent.93 - If a mission was touched, launch only when the user asked for runtime validation or the change is risky enough to justify it.9495## Reference Use9697- Read `references/app-build.md` when the project build layout is missing, broken, or unfamiliar.98- Read `references/app-patterns.md` before implementing nontrivial app logic.99- Read `references/app-examples.md` when choosing a representative app to inspect in the resolved `MOOS_IVP_ROOT`.100101## Validation Checklist102103- App has a project build entry.104- App links only the libraries it actually needs, plus `apputil` for AppCasting and `mbutil` for common utilities.105- `OnNewMail()` handles or deliberately ignores subscribed mail without warning on `APPCAST_REQ`.106- `registerVariables()` lists every subscribed variable.107- `showInterfaceAndExit()` matches actual subscriptions/publications.108- Build succeeds, or the blocker is reported with the exact missing dependency/error.109- `--help`, `--example`, and `--interface` reflect the real app and do not110 crash when supported.111- Runtime config, when relevant, is verified through `pAntler` with112 `ProcessConfig = <AppName>`, not by direct app-by-path execution alone.113- For clean-host or relocatable claims, run114 `<skill-dir>/scripts/check_portable_paths.sh <project-dir>`, resolving115 `<skill-dir>` as the directory containing this `SKILL.md`, and include a116 clean build with a caller-supplied non-default `MOOS_IVP_ROOT`.