Workflows
Dev
Run a supervised local stack with sentinel dev: a config file, a terminal UI, and per-service start, stop, restart, and copy-log controls.
sentinel dev runs a small supervisor and a terminal UI for the dev stack you actually use day to day. You declare your services in .sentinel.yml once, and from then on sentinel dev starts them, tails their logs, ingests them, and lets you stop, restart, and inspect a single service without leaving the terminal.
Use sentinel dev when you want one command to bring up multiple long-running processes (a server, a worker, a Compose stack), keep them grouped under one project, and surface failures in the same Sentinel database as the rest of your local triage.
First run
From the repo root:
sentinel dev
If .sentinel.yml does not exist and the terminal is interactive, sentinel dev drops into the init wizard. The wizard:
- looks at the workspace for likely services (Compose files, package scripts, common dev scripts)
- presents each candidate one at a time with
Y / e / n(accept, edit, skip) - lets you add manual services after the auto-detected ones
- writes
.sentinel.ymlat the repo root
You can also run the wizard explicitly without starting anything:
sentinel dev init
If you are running non-interactively (CI, scripts) and .sentinel.yml is missing, sentinel dev exits with an error pointing you at sentinel dev init.
.sentinel.yml
A minimal config for one Node command service and one Docker Compose service:
version: 1
defaults:
group: default
project: my-app
confirm_before_start: true
services:
- name: api
type: command
path: ./api
command: npm run dev
- name: db
type: compose_service
path: ./infra
service: postgres
groups:
- name: default
services: [api, db]
- name: api-only
services: [api]
Field reference:
| Field | Meaning |
|---|---|
version | Config schema version. Currently 1. |
defaults.group | Group used when --group is not set. |
defaults.project | Project name applied when --project is not set on the CLI. |
defaults.confirm_before_start | Show a preflight prompt before launching. Default true. Set to false to skip the prompt without --yes. |
services[].name | Stable service name. Used in logs, metrics, and the TUI sidebar. |
services[].type | command for a process Sentinel starts, compose_service for a Docker Compose service. |
services[].path | Working directory for the service. For command, the shell command runs there. For compose_service, Docker Compose runs from that directory, so it should contain compose.yaml, compose.yml, docker-compose.yaml, or docker-compose.yml. Relative paths resolve against .sentinel.yml. |
services[].cwd | Legacy alias for path. New configs should use path. |
services[].command | Shell command for command services. Runs through sh -lc so login-shell tools like nvm, pyenv, and rbenv are visible. On Windows it runs via cmd /C. |
services[].service | Compose service name in the Compose project rooted at path. |
services[].depends_on | Other service names that should start first. |
groups[].name | Group name used by --group. |
groups[].services | Subset of services[].name to start for this group. |
Compose services are supervised with docker compose up -d <service> followed by docker compose logs -f <service> in the service path. In normal mode, Sentinel treats that Compose service as part of the supervised session and may run docker compose stop <service> on shutdown. If a Compose service is already running and you want Sentinel to leave it running, use sentinel dev --attach-only.
Day-to-day commands
| Command | Best when… |
|---|---|
sentinel dev | You want to bring up the default group and tail it. |
sentinel dev --group <name> | You have multiple groups (full stack, API-only, workers-only) and want one of them. |
sentinel dev --attach-only | The services are already running and you only want to ingest their logs. Skips starting command services. |
sentinel dev --dry-run | You want to see the resolved plan (which services in which order) without starting anything. |
sentinel dev --yes | You want to skip the preflight confirmation prompt. |
sentinel dev init | You need to create or recreate .sentinel.yml. |
sentinel dev status | You want to know if a session is already running for this workspace and which services it brought up. Add --json for scripts. |
sentinel dev stop | You started a session in another terminal and want to stop it from here. Add --force if graceful shutdown does not return within 8 seconds. |
sentinel dev doctor | You suspect a missing tool. Checks docker, docker compose, and the first binary in each command service. Add --group <name> to scope the check, --json for machine-readable output. |
Inside the TUI
The dev TUI shows a sidebar with services and a log pane on the right. Drag-select still works in the pane (the TUI does not capture the mouse wheel), so you can copy text the normal terminal way.
| Key | Action |
|---|---|
j / k | Move between services |
a | Show all services combined |
s | Stop the selected service |
r / Enter | Start or restart the selected service |
c | Copy the visible log pane to the system clipboard |
p / f | Pause or resume follow mode |
PageUp / PageDown | Scroll logs (auto-pauses follow) |
/ | Filter visible logs (Esc or Enter to exit) |
m | Toggle the metrics strip |
o | Open the local web UI for deeper triage |
? | Toggle help |
q / Ctrl+C | Quit and stop the session |
The metrics strip (toggle with m) shows CPU% and resident memory per service. For command services it walks the process tree from the spawned PID. For compose_service services it walks the container’s main PID. It updates a few times a second; numbers round at the bar level, so don’t read tenths of a percent into them.
Logs, redaction, and the clipboard
Every line a service prints goes through two paths inside sentinel dev:
- The raw line is sent to the parser and triage engine, the same as
sentinel runorsentinel stdin. - A copy is appended to the in-memory log buffer that backs the TUI pane.
When --redact is on (the default), the buffered copy is redacted before it is stored. So the TUI pane already shows redacted logs, and the c keybinding ships that same redacted text to the clipboard. If you turn redaction off explicitly (--redact=false), the TUI shows raw bytes and the clipboard receives raw bytes. Bearer tokens, JWTs, AWS keys, and similar patterns are stripped only while redaction is on.
Project scoping in dev
sentinel dev resolves the project name in this order:
--projecton the CLI, if setdefaults.projectin.sentinel.yml- the workspace directory name, normalized to lowercase with spaces changed to dashes
dev, if the workspace name cannot be resolved
That project is what every fingerprint, occurrence, and trace ingested during the session is scoped to. The local web UI’s project dropdown will show it after the first event lands. See Projects for how scoping interacts with sentinel history, sentinel traces, and the UI.
OpenTelemetry inside dev
For each command service, sentinel dev injects the same OTLP variables that sentinel run injects:
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobufOTEL_EXPORTER_OTLP_ENDPOINT=<local OTLP/HTTP receiver>OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=<endpoint>/v1/tracesOTEL_RESOURCE_ATTRIBUTESis merged withsentinel.session_idandsentinel.project
If your service uses an OTel SDK that respects these env vars, traces show up in sentinel traces and on the issue detail page automatically. Compose services are not instrumented for you. If you want their traces too, set the same env vars in their Compose file.
See OpenTelemetry for the full picture.
How sessions interact
Only one sentinel dev session runs per workspace at a time. The supervisor records its PID and the resolved state in ~/.sentinel/run/<workspace-hash>/state.json. sentinel dev status and sentinel dev stop find that file and act on it.
If a process crashes or you kill -9 the supervisor, the state file may be left behind. Re-running sentinel dev cleans it up. sentinel dev stop will detect a stale state file and tell you so.
Troubleshooting
If something does not behave the way you expect, try:
sentinel dev doctorto confirm Docker, Compose, and per-service binaries are installed.sentinel dev --dry-runto see the resolved plan.sentinel dev status --jsonto inspect the live session.sentinel dev stop --forceif a graceful stop times out.
For a list of common failure modes (missing config, OTLP port already in use, redaction surprises), see Troubleshooting.