Retour aux mises à jour
New releaseSep 4, 2026

sonar v0.4.1

Outil CLI pour inspecter et gérer les services écoutant sur les ports localhost.

Partager
██████    ███    ██████    ██    ██████
██           ██      ██  ██  ██      ██
██      ██   ██  ██  ██  ██  ██      ██
  ██  ██   ██  ██  ██  ██  ██  ████
    ██  ██       ██  ██  ██  ██  ██  ██
██████    ███    ██  ██  ██  ██  ██  ██

Sachez ce qui tourne sur votre machine.

Sonar affiche tout ce qui écoute sur localhost et le met en ordre : chaque port appartient à un groupe — normalement le dépôt depuis lequel il a été démarré — et à l'intérieur de ce groupe à un service nommé. Démarrez vos serveurs de développement avec sonar start et tout le projet devient une seule chose que vous pouvez lister sous forme d'arbre, attendre, suivre et arrêter avec une seule commande. Les conteneurs Docker, les projets Compose et les processus que vous avez démarrés à la main sont également détectés, sans aucune configuration.

$ sonar list --tree
my-app  (3 ports, running)                        ~/code/my-app
├─ 5432  db          postgres:17                  http://localhost:5432
├─ 5173  frontend    vite (v5.4)                  http://localhost:5173
└─ 8000  api         uvicorn app:app              http://localhost:8000
ungrouped (1 port)
└─ 3000  next-server (v16.1.6)                    http://localhost:3000

Installation

Homebrew (macOS / Linux)

brew install raskrebs/sonar/sonar

Homebrew 6 refuse les formules des taps tiers tant que vous n'avez pas approuvé le tap une fois (Error: Refusing to load formula raskrebs/sonar/sonar from untrusted tap) :

brew trust raskrebs/sonar

Script d'installation

curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.sh | bash

Télécharge le dernier binaire dans ~/.local/bin et l'ajoute à votre PATH si nécessaire. Redémarrez votre terminal ou exécutez source ~/.zshrc.

Sur Windows (PowerShell) :

irm https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.ps1 | iex

Emplacement d'installation personnalisé :

curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.sh | SONAR_INSTALL_DIR=/usr/local/bin bash

Installer une version spécifique :

curl -sfL https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.sh | SONAR_VERSION=vX.Y.Z bash
$env:SONAR_VERSION="vX.Y.Z"; irm https://raw.githubusercontent.com/raskrebs/sonar/main/scripts/install.ps1 | iex

Utilisation de Go

go install github.com/raskrebs/sonar@latest

Complétions du shell (complétion par tabulation des numéros de port) :

sonar completion zsh > "${fpath[1]}/_sonar"   # zsh
sonar completion bash > /etc/bash_completion.d/sonar  # bash
sonar completion fish | source                 # fish

Soixante secondes

Décrivez comment votre projet s'exécute dans un sonar.yaml à la racine du dépôt, à la place d'un dev.sh :

name: my-app
services:
  - name: db
    cmd: docker compose up db
    port: 5432
  - name: api
    cmd: uv run uvicorn app:app --port ${port}
    port: auto
    depends_on: [db]
  - name: frontend
    cmd: npm run dev -- --port ${port} --strictPort
    port: auto
    depends_on: [api]
    env:
      VITE_API_URL: ${api.url}

Puis démarrez-le :

sonar start
  ✓ db        http://localhost:5432   pid 41022  ~/.config/sonar/logs/my-app/db.log
  ✓ api       http://localhost:21408  pid 41040  ~/.config/sonar/logs/my-app/api.log
  ✓ frontend  http://localhost:21409  pid 41077  ~/.config/sonar/logs/my-app/frontend.log

3 started
following the logs; Ctrl+C stops the 3 services started here
api      | INFO:     Uvicorn running on http://127.0.0.1:21408
frontend | VITE v5.4  ready in 312 ms

Sonar choisit un port libre pour chaque service port: auto et indique à chaque service où se trouvent les autres, de sorte qu'un second worktree s'exécute à côté du premier sans qu'un seul port n'entre en conflit. sonar start -d fait la même chose en arrière-plan, et sonar down l'arrête et libère les ports. Dans un autre terminal :

sonar list --tree
my-app  (3 ports, running)                        ~/code/my-app
├─ 5432   db          postgres:17                 http://localhost:5432
├─ 21408  api         uvicorn app:app             http://localhost:21408
└─ 21409  frontend    vite (v5.4)                 http://localhost:21409

Pas de sonar.yaml ? sonar start -- npm run dev exécute une commande en tant que service nommé, et sonar list et sonar kill fonctionnent sur tout ce qui écoute.

Les exemples ci-dessous marqués # check sont exécutés sur une version fraîche par scripts/readme-check.sh à chaque exécution de la CI.

Commandes

sonar list

sonar list
sonar list --tree
sonar list --group my-app
sonar list --json
# check
sonar list --stats             # CPU, memory, threads, uptime, state
sonar list --health            # HTTP health checks
sonar list --filter docker     # only Docker ports
sonar list --sort name         # port | pid | name | type
sonar list -a                  # include desktop apps
sonar list -c port,process,group,cpu,mem
sonar list --host user@server  # scan a remote machine over SSH

Les colonnes par défaut sont port, process, group, container, image, containerport, url, où process affiche le nom que vous avez donné au port (sonar rename), puis le nom du service, puis ce qui a été détecté.

Colonnes disponibles : port, process, pid, type, url, group, cpu, mem, threads, uptime, state, connections, health, latency, container, image, containerport, compose, project, user, bind, ip.

Les applications de bureau et les services système qui se trouvent écouter — Figma, Discord, Spotify, ControlCenter, les bundles .app de macOS, les démons de /System/Library/ — sont masqués sauf si vous passez -a.

sonar start

Démarrer un projet à partir de son sonar.yaml :

sonar start                    # every service in the nearest sonar.yaml
sonar start api frontend       # only these (they still wait for their dependencies)
sonar start ../other-project   # the sonar.yaml in or above another directory
sonar start -d                 # in the background, like `sonar up`

Au premier plan, sonar démarre les services via le démon, suit leurs journaux avec le nom du service devant chaque ligne, et lorsque vous appuyez sur Ctrl+C arrête les services qu'il a démarrés. Un service qui était déjà en cours d'exécution est laissé tranquille, et sonar revient de lui-même une fois que chaque service qu'il a démarré s'est terminé.

Les arguments avant -- désignent un répertoire ou des services ; tout ce qui suit -- est une commande. Ou exécutez une commande en tant que service nommé dans un groupe :

sonar start -- npm run dev
sonar start --group my-app --name frontend -- npm run dev
sonar start --port 5173 -- npm run dev        # expected port, before it binds
sonar start --detach --name api -- uv run uvicorn app:app
sonar start --list

Rien ne doit être passé :

  • Group — --group, sinon le name dans le sonar.yaml le plus proche, sinon le nom du répertoire de la racine git (un worktree devient repo@worktree), sinon le nom du répertoire courant.
  • Name — --name, sinon le service sonar.yaml dont le cmd correspond, sinon déduit de la commande (npm run dev → dev, uv run api → api, python -m uvicorn → uvicorn, ./dev.sh → dev.sh).
  • Port — --port est un indice, pas une liaison : l'exécution apparaît comme starting jusqu'à ce que le port soit réellement en écoute, et le daemon l'utilise pour faire correspondre le processus au port.

Catégories