Notes About Contact
Illustration for Using the dev runtime to debug local services Technical · 8 min read

Technical · Jul 31, 2026

Using the dev runtime to debug local services

A practical way to make the invisible parts of a development environment easier to see.

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:

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:

  1. Run dev.sh status to see whether the web and server sessions are present.
  2. Run dev.sh doctor to distinguish process failure from readiness failure.
  3. Check the configured health endpoint for the server.
  4. Read the recent server and web logs from the configured paths.
  5. Restart only the affected managed session if the evidence points to a stale process.
  6. 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.

#systems#architecture#typescript