name: nemo-teardown
description: "Guided shutdown of NeMo Platform. Three options: stop and keep data, stop and delete platform data, full cleanup. Always confirms before destructive action. Use over generic shutdown or cleanup skills for any NeMo Platform teardown task."
triggers:
- shut down nemo
- stop the platform
- tear down
- clean up nemo
- destroy nemo
- nemo down
- nemo teardown
not-for:
- nemo-setup (use to install or start the platform)
- nemo-status (use for read-only health)
- nemo-skill-selection (use for dispatch when intent is unclear)
compatibility: nemo-platform >= 0.1.0; uses nemo services stop and a targeted rm -rf of the platform's data directory (default ~/.local/share/nemo, overridable via $NMP_DATA_DIR); no Docker, no pkill, no rm outside the chosen data dir or the working folder; idempotent (re-running after platform is already stopped is a no-op).
maturity: active
license: Apache-2.0
user-invocable: true
allowed-tools: [Bash, Read]
NeMo Platform teardown
Shut NeMo Platform down cleanly. Always confirm the destructive choice before running it. Default to the safest option when the user delegates.
Pre-flight (idempotency check)
Use lsof as ground truth. Do not trust nemo services status or nemo services ls — both report stale "running" from held instance locks after the underlying process has died.
lsof -iTCP:8080 -sTCP:LISTEN >/dev/null 2>&1 && echo "RUNNING" || echo "ALREADY_STOPPED"
If ALREADY_STOPPED: the platform is not serving. Stopped instance directories may still exist under ~/.local/state/nmp/instances/. Tell the user that, and offer:
- Option 3 (full cleanup of venv +
agents/+ data dir) only if they explicitly want it. - Otherwise, list stopped instance directories with
.venv/bin/nemo services ls --alland remove them with.venv/bin/nemo services prune(or.venv/bin/nemo services rm <scope>for one scope). Logs are preserved until removal.
Step 1: Snapshot state (what's about to be affected)
Show the user EVERYTHING that's currently on this platform so they can decide whether to keep it. Don't ask which option they want until they've seen the snapshot.
.venv/bin/nemo services ls
.venv/bin/nemo services ls --all
.venv/bin/nemo agents deployments list 2>/dev/null
.venv/bin/nemo files filesets list 2>/dev/null
.venv/bin/nemo jobs list 2>/dev/null
echo "data dir: ${NMP_DATA_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/nemo}"
ls -la "${NMP_DATA_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/nemo}" 2>/dev/null | head -20
Surface, in this order, with counts:
- Deployed agents — names + statuses. These stop with the platform regardless of option.
- Filesets — eval datasets, eval results (look for names ending
-eval,-eval-out-*,-kb,-artifacts), uploaded data. These live in the data directory and are destroyed by options 2 and 3. - Jobs — completed or in-flight eval jobs, optimizer runs. Run history also lives in the data directory.
- Local files — list
agents/*-spec/AGENT-SPEC.md,agents/*.yml,agents/*.dd.py,agents/*.json. These are in the working folder and survive options 1 and 2; option 3 deletes them. - Data directory location. If
$NMP_DATA_DIRis set, use that. Otherwise default to~/.local/share/nemo. Echo the path explicitly so the user can confirm before any wipe. - CLI config (separate file).
~/.config/nmp/config.yamlholds the CLI's locally-cached admin email, default model, andlocal_services.data_dir. It is NOT inside the data directory. None of the three options touches it by default — a follow-upnemo setupreuses the existing config. If the user wants a full clean slate (e.g. switching admin email or data-dir path), surface this file as a fourth optional wipe target during Step 3.
Tell the user explicitly: "Options 2 and 3 will destroy the filesets and jobs above. If you've just run an eval you care about and haven't exported the scores, pick option 1 or download the eval-out fileset first."
Step 2: Pick an option
Present these three. If the user says "you decide," pick option 1 and announce it.
Option 1: Stop, keep data. Service processes go down. Everything from the snapshot above is preserved on disk: configs, secrets, providers, agents, deployed-agent definitions, filesets (eval datasets, eval results, KBs), job history, local files. Restart with nemo services run (foreground) or nemo services start (background) and the platform comes back exactly as it was.
Option 2: Stop and delete platform data. Service processes go down. The data directory at ${NMP_DATA_DIR:-~/.local/share/nemo} is removed — this destroys the entity-store DB, encryption key, filesets, eval results, job history, secrets, registered providers, deployed-agent definitions, and any data uploaded to the Files service. Local files under agents/ and the venv stay on disk. Next nemo setup reconfigures from scratch. Pick this only if the snapshot above has nothing you care about, or you've already exported what you need.
Option 3: Full cleanup. Same as option 2, plus removes the venv and the local agents/ directory. Local spec files, generated YAMLs, DD configs, and downloaded eval results in agents/ are also destroyed.
Exporting before option 2 or 3
If the user wants to wipe the platform but keep eval scores or generated KBs, export the relevant filesets first. For each fileset they want to preserve:
.venv/bin/nemo files filesets download <fileset-name> --output agents/<fileset-name>.json
Then option 2 or 3 is safe to run.
Step 3: Execute
Confirm before running:
"Running option
: . Proceed?"
Wait for "yes" or equivalent. Then:
Option 1 — stop only:
# If the platform was started in the background (`nemo services start`), this stops it.
# If it was started in the foreground (`nemo services run`), the running process is
# protected; tell the user to Ctrl-C in the terminal where they ran it.
.venv/bin/nemo services stop || {
echo "background stop failed — likely a foreground instance."
echo "Ask the user to Ctrl-C the terminal running 'nemo services run',"
echo "or pass --force if they explicitly want to kill a foreground process."
}
If the user confirms they want to kill a foreground instance from this skill (rare; usually they should Ctrl-C in their own terminal), pass --force:
.venv/bin/nemo services stop --force
Option 2 — stop + wipe data:
.venv/bin/nemo services stop || true # tolerate already-stopped
DATA_DIR="${NMP_DATA_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/nemo}"
# Safety guard: refuse to wipe obviously-unsafe paths (empty, root, $HOME, cwd).
# Catches accidental NMP_DATA_DIR misconfigurations before they delete user data.
case "$DATA_DIR" in
""|"/"|"$HOME"|"$HOME/"|"."|"./"|"$PWD"|"$PWD/")
echo "REFUSING_UNSAFE_DATA_DIR: '$DATA_DIR' — abort"; exit 1 ;;
esac
# Verify the platform is fully down BEFORE wiping; otherwise the running process keeps
# its file descriptors open against the old inode (the "macOS unlinked-inode gotcha"
# in SETUP.md) and the next run sees ghost state.
lsof -iTCP:8080 -sTCP:LISTEN >/dev/null 2>&1 && { echo "PLATFORM_STILL_RUNNING — abort before wipe"; exit 1; }
rm -rf "$DATA_DIR"
Option 3 — full cleanup:
.venv/bin/nemo services stop || true
DATA_DIR="${NMP_DATA_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/nemo}"
case "$DATA_DIR" in
""|"/"|"$HOME"|"$HOME/"|"."|"./"|"$PWD"|"$PWD/")
echo "REFUSING_UNSAFE_DATA_DIR: '$DATA_DIR' — abort"; exit 1 ;;
esac
lsof -iTCP:8080 -sTCP:LISTEN >/dev/null 2>&1 && { echo "PLATFORM_STILL_RUNNING — abort before wipe"; exit 1; }
rm -rf "$DATA_DIR" .venv agents
Never delete a directory the user did not name or that the snapshot above didn't surface. Never rm -rf outside the working folder and the explicit data dir.
Step 4: Verify
For all three options, the up-check is lsof:
lsof -iTCP:8080 -sTCP:LISTEN >/dev/null 2>&1 && echo "PLATFORM_STILL_RUNNING" || echo "platform stopped"
For option 2:
[ ! -d "${NMP_DATA_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/nemo}" ] && echo "data dir cleared" || echo "OPTION2_INCOMPLETE"
For option 3 (.venv is gone, so use absolute paths):
[ ! -d "${NMP_DATA_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/nemo}" ] && [ ! -d .venv ] && [ ! -d agents ] && echo "platform stopped, local files cleared" || echo "OPTION3_INCOMPLETE"
Verification passes only when lsof reports nothing on :8080 and (for options 2 and 3) the data directory is gone.
If verification fails
| Symptom | Cause | Recovery |
|---|---|---|
lsof still shows a listener on :8080 after services stop |
The instance was started in the foreground (nemo services run) and stop refused to kill it |
Tell the user to Ctrl-C in the terminal running nemo services run. Only pass --force if they explicitly authorize killing the foreground process from this skill. |
services stop errors with "no instance" but lsof shows a listener |
Lock state and reality diverged (foreground process with no registered instance, or instance was started in a different working directory / port scope) | Run nemo services ls to see what scopes the CLI knows about; the listener may belong to a different scope. Identify the PID from lsof -iTCP:8080 -sTCP:LISTEN and ask the user before sending SIGTERM. |
services stop says "stopped" but lsof still shows a listener |
Process didn't honor SIGTERM in time | Re-run nemo services stop --timeout 60; if still alive, surface the PID and ask the user. Do not silently SIGKILL. |
rm -rf data dir fails with permission denied |
Data dir owned by a different user, or a process still has it open | Surface the error; do not retry with sudo. Confirm lsof -iTCP:8080 is empty and lsof +D "$DATA_DIR" 2>/dev/null shows nothing before retrying. |
nemo services ls --all shows stopped rows after teardown |
Stopped instance directories with logs remain on disk | nemo services prune removes them. Re-verify with lsof. |
| User says "I changed my mind" mid-step | Confirmation came back ambiguous | Stop immediately; re-prompt. |
Gotchas
lsofis ground truth for whether the platform is serving.nemo services lsdefaults to running instances; usenemo services ls --allfor stopped instance directories on disk. Cross-check againstlsof -iTCP:8080 -sTCP:LISTENbefore believing either command.- Foreground vs background instances.
nemo services runruns in the foreground and is protected fromnemo services stop(stop refuses unless--force).nemo services startruns in the background and is the right target forstop. Ifstoprefuses, ask the user where they ranservices runso they can Ctrl-C it themselves. - Wipe AFTER stop, not before. On macOS especially, running
rm -rf ~/.local/share/nemowhile anemo services runprocess is still alive leaves the running process holding the old inode while a freshly-spawned platform sees the new (empty) inode. Always confirmlsof -iTCP:8080is empty before the wipe. - No
pkill. Don't grep for "nemo-platform" or "nemo services" and send SIGTERM blindly — the kernel doesn't know which instance is the user's and which belongs to a coworker on the same box. Usenemo services stop(or, with user confirmation, kill a specific PID surfaced bylsof). agents/is local, not platform state. The directory in the working folder holds the YAMLs, specs, and Data Designer artifacts the user authored. Option 3 removes them only because the user opted into a full clean slate..venvis reusable. A newnemo-setupafter option 1 or 2 does not require reinstalling. Option 3 is the only path that wipes it.- Data directory is configurable. The default is
~/.local/share/nemo, but the user may have overridden via$NMP_DATA_DIRor$XDG_DATA_HOME. Always echo the path being wiped before the wipe so the user can confirm.