Using the dev-runtime Skill to Debug Local Services
Local development gets fragile when “the server is running” means nothing more than a terminal tab containing a startup message. A process can still be warming up, listening on the wrong port, missing an environment file, or failing every real health check.
The dev-runtime skill gives local
services a small operating model: configure the sessions once, then use shared
commands to start, inspect, verify, and stop them. The important idea is simple:
The skill is developed in the motia/agent-skills-dev repository.
Never infer service readiness from terminal text alone. Use the configured status and doctor output as the source of truth.
What the skill manages
The skill reads project configuration instead of hardcoding service names or ports into debugging commands. Four files define the runtime contract:
.agent/config/runtime.envcontains global settings, required tools, and environment-file expectations..agent/config/runtime.sessions.tsvlists managed sessions, their working directories, commands, and log files..agent/config/runtime.ports.tsvdocuments expected port bindings..agent/config/runtime.health.tsvdefines HTTP health or readiness checks.
In a typical workspace, the session table can describe the API server, worker, web app, admin app, blog, UI watcher, and browser extension without requiring the skill itself to know anything about the application architecture.
That separation matters. Runtime tooling stays reusable, while each project retains ownership of its own commands and readiness requirements.
Start with the doctor
Before debugging a local issue, run the doctor:
./.agents/skills/dev-runtime/scripts/dev.sh doctor
The doctor checks the categories that are easy to overlook when reading a terminal: required tools, compose state, managed sessions, port bindings, HTTP health checks, environment files, recent logs, and any project-specific doctor extensions.
This makes the first question concrete. Instead of asking, “Did npm start?”, you can ask, “Which configured dependency is unhealthy, and what evidence shows that?”
Use status for a quick snapshot
When you need a fast view during development, use the configured status command:
./.agents/skills/dev-runtime/scripts/status.sh
Status is useful for the common loop: make a change, check whether the relevant session is alive, inspect the health result, and then read only the logs that correspond to the failure.
An open port is not enough. A process may bind successfully while its database
connection, migrations, dependencies, or application routes are broken. A
configured readiness endpoint gives a much stronger signal than ss -ltnp
alone.
Use the lifecycle router consistently
The main router exposes the normal lifecycle:
./.agents/skills/dev-runtime/scripts/dev.sh start
./.agents/skills/dev-runtime/scripts/dev.sh status
./.agents/skills/dev-runtime/scripts/dev.sh doctor
./.agents/skills/dev-runtime/scripts/dev.sh stop
The project may expose the same interface through npm, for example:
npm run dev start
npm run dev doctor
The lifecycle rules are intentionally conservative. Assume services may already be running, reuse managed sessions, and avoid creating duplicate processes. Stop the stack only when the task requires it, and never tear down Docker volumes as part of ordinary troubleshooting.
Read the right logs
Logs belong to the session configuration. If the server is configured with
logs/server.log, the worker with logs/worker.log, and the blog with
logs/blog.log, inspect those paths rather than guessing a universal
server.log name:
tail -n 200 logs/server.log
tail -n 200 logs/worker.log
For a tmux-managed session, capture recent terminal output without entering an interactive scrollback view:
tmux capture-pane -pt server -S -200
The best debugging sequence is usually doctor or status first, then the configured log for the unhealthy session, then a focused health or dependency check. This keeps a large amount of startup noise from obscuring the useful evidence.
A repeatable debugging loop
Suppose the web UI appears blank after an API change. A disciplined loop looks like this:
- Run
dev.sh statusto see whether the web and server sessions are present. - Run
dev.sh doctorto distinguish process failure from readiness failure. - Check the configured health endpoint for the server.
- Read the recent server and web logs from the configured paths.
- Restart only the affected managed session if the evidence points to a stale process.
- Run doctor again and verify the UI through the normal application route.
The final doctor result matters as much as the first one. A restart command is an action; it is not proof that the system recovered.
Why this small discipline pays off
Runtime bugs often look like application bugs because several failure modes surface in the browser in the same way: a blank page, a timeout, or a generic network error. Separating session state, ports, health checks, environment files, and logs narrows the search quickly.
The skill also makes team instructions more portable. A new contributor can learn one runtime workflow without memorizing which terminal tab starts which service. CI and local debugging can refer to the same configured readiness contract, while project-specific checks remain isolated in doctor extensions.
The result is not elaborate infrastructure. It is a shared definition of “running,” backed by evidence, that makes local development calmer and easier to repair.