---
description: Use PortMarshal for local dev-server startup, port conflicts and guarded service stops.
alwaysApply: true
---

# PortMarshal

Use PortMarshal for local development servers on macOS/Linux. Requires PortMarshal 0.9.0 or newer.
Preserve the user's requested project and command; these examples do not authorize unrelated service changes.

## Diagnose and preserve identity

Run `portmarshal --version` and `portmarshal doctor --project . --json` before first use in the project.
Doctor is read-only: exit 0 can include warnings; inspect `status` and `complete`. An incomplete scan does not
prove that a port is free or that a service is abandoned.

Preserve an existing `PORTMARSHAL_OWNER` on every command. Without it, PortMarshal recognizes available
Codex thread/session IDs; other hosts retain project-level fallback unless explicitly configured.
If the session needs an explicit owner, use one stable non-secret value unique to that session and pass
it consistently on each invocation. Do not generate an owner per command, share one constant across
sessions, or assume an `export` in one shell tool call persists into another. Do not print owner values.

## Start and inspect

Use detached mode when the agent needs to continue after the server is ready:

```bash
portmarshal run -d web --prefer 5173 -- pnpm vite --port {port}
portmarshal run -d api --prefer 3000 --ready-url /health --wait-timeout 60 -- pnpm start
portmarshal logs web -n 50
portmarshal list --services --project . --json
portmarshal whois 5173 --json
```

Use the actual returned port for `whois`; the preferred port may be occupied. Frameworks must consume
`PORT` or the substituted `{port}` flag. For foreground supervision use
`portmarshal run web --prefer 3000 -- npm run dev`; use bare `claim` only when another tool must own the lifecycle.
Readiness failure includes log output and cleans up only the verified failed run. Logs can contain
application secrets: inspect locally and do not paste them into shared reports without reviewing them.

## Conflicts and stopping

`portmarshal stop <port>` applies the project/session guard; use it only for a service the user intends
to stop. `release` removes a claim without stopping its listener. Preview cleanup with `portmarshal gc --dry-run`.

Exit code 3 may mean a live previous instance, a different session owner, or insufficient ownership
evidence. Inspect `whois <port> --json` and the diagnostic message. Preserve another session's healthy
service; choose a separate service name/port when appropriate. A same-project path or `detached` label
alone does not authorize taking over a service. Do not blindly retry with `--restart`, change the owner
to evade the guard, invoke raw process signals, or use `--force` without explicit authorization covering
that target. Existing user authorization remains valid; do not ask for it a second time.

Stop exit codes: 0 completed, 2 no listener, 3 blocked. Diagnose cleanup with `gc --dry-run`; plain `gc`
can release stale claims. Doctor never repairs permissions, migrates state, releases claims or stops services.


Cursor: this rule does not infer a conversation ID. Preserve an explicitly supplied owner or report project-level fallback.
