sentinel docs

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.yml at 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:

FieldMeaning
versionConfig schema version. Currently 1.
defaults.groupGroup used when --group is not set.
defaults.projectProject name applied when --project is not set on the CLI.
defaults.confirm_before_startShow a preflight prompt before launching. Default true. Set to false to skip the prompt without --yes.
services[].nameStable service name. Used in logs, metrics, and the TUI sidebar.
services[].typecommand for a process Sentinel starts, compose_service for a Docker Compose service.
services[].pathWorking 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[].cwdLegacy alias for path. New configs should use path.
services[].commandShell 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[].serviceCompose service name in the Compose project rooted at path.
services[].depends_onOther service names that should start first.
groups[].nameGroup name used by --group.
groups[].servicesSubset 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

CommandBest when…
sentinel devYou 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-onlyThe services are already running and you only want to ingest their logs. Skips starting command services.
sentinel dev --dry-runYou want to see the resolved plan (which services in which order) without starting anything.
sentinel dev --yesYou want to skip the preflight confirmation prompt.
sentinel dev initYou need to create or recreate .sentinel.yml.
sentinel dev statusYou want to know if a session is already running for this workspace and which services it brought up. Add --json for scripts.
sentinel dev stopYou 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 doctorYou 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.

KeyAction
j / kMove between services
aShow all services combined
sStop the selected service
r / EnterStart or restart the selected service
cCopy the visible log pane to the system clipboard
p / fPause or resume follow mode
PageUp / PageDownScroll logs (auto-pauses follow)
/Filter visible logs (Esc or Enter to exit)
mToggle the metrics strip
oOpen the local web UI for deeper triage
?Toggle help
q / Ctrl+CQuit 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:

  1. The raw line is sent to the parser and triage engine, the same as sentinel run or sentinel stdin.
  2. 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:

  1. --project on the CLI, if set
  2. defaults.project in .sentinel.yml
  3. the workspace directory name, normalized to lowercase with spaces changed to dashes
  4. 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/protobuf
  • OTEL_EXPORTER_OTLP_ENDPOINT=<local OTLP/HTTP receiver>
  • OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=<endpoint>/v1/traces
  • OTEL_RESOURCE_ATTRIBUTES is merged with sentinel.session_id and sentinel.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 doctor to confirm Docker, Compose, and per-service binaries are installed.
  • sentinel dev --dry-run to see the resolved plan.
  • sentinel dev status --json to inspect the live session.
  • sentinel dev stop --force if a graceful stop times out.

For a list of common failure modes (missing config, OTLP port already in use, redaction surprises), see Troubleshooting.