العودة إلى التحديثات
New releaseSep 4, 2026

sonar v0.4.1

أداة سطر أوامر لفحص وإدارة الخدمات التي تستمع على منافذ localhost

مشاركة
██████    ███    ██████    ██    ██████
██           ██      ██  ██  ██      ██
██      ██   ██  ██  ██  ██  ██      ██
  ██  ██   ██  ██  ██  ██  ██  ████
    ██  ██       ██  ██  ██  ██  ██  ██
██████    ███    ██  ██  ██  ██  ██  ██

اعرف ما الذي يعمل على جهازك.

يعرض Sonar كل ما يستمع على localhost ويرتّبه: كل منفذ ينتمي إلى مجموعة — عادةً المستودع الذي بدأ منه — وداخل تلك المجموعة إلى خدمة مُسمّاة. ابدأ خوادم التطوير الخاصة بك باستخدام sonar start وسيصبح المشروع بأكمله شيئًا واحدًا يمكنك سرده كشجرة، والانتظار له، وتتبّع سجلاته، وإيقافه بأمر واحد. كما يتم التقاط حاويات Docker ومشاريع Compose والعمليات التي بدأتها يدويًا، دون أي إعداد.

$ 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

التثبيت

Homebrew (macOS / Linux)

brew install raskrebs/sonar/sonar

Homebrew 6 يرفض الصيغ من النقرات الخارجية حتى تثق بالنقرة مرة واحدة (Error: Refusing to load formula raskrebs/sonar/sonar from untrusted tap):

brew trust raskrebs/sonar

نص التثبيت

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

يقوم بتنزيل أحدث ملف تنفيذي إلى ~/.local/bin ويضيفه إلى PATH الخاص بك إذا لزم الأمر. أعد تشغيل الطرفية أو نفّذ source ~/.zshrc.

على Windows (PowerShell):

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

موقع تثبيت مخصص:

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

تثبيت إصدار محدد:

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

استخدام Go

go install github.com/raskrebs/sonar@latest

إكمالات الصدفة (إكمال تلقائي لأرقام المنافذ):

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

ستون ثانية

صف كيفية تشغيل مشروعك في sonar.yaml في جذر المستودع، بدلاً من 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}

ثم شغّله:

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 يختار منفذًا حرًا لكل خدمة port: auto ويخبر كل خدمة بأماكن الخدمات الأخرى، بحيث يعمل worktree ثانٍ بجانب الأول دون تعارض أي منفذ. يفعل sonar start -d الشيء نفسه في الخلفية، ويوقفه sonar down ويعيد المنافذ. في طرفية أخرى:

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

لا يوجد sonar.yaml؟ يقوم sonar start -- npm run dev بتشغيل أمر واحد كخدمة مُسمّاة، ويعمل sonar list و sonar kill على أي شيء يستمع.

الأمثلة أدناه المعلَّمة بـ # check تُنفَّذ مقابل بناء جديد بواسطة scripts/readme-check.sh في كل تشغيل لـ CI.

الأوامر

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

الأعمدة الافتراضية هي port، process، group، container، image، containerport، url، حيث يعرض process الاسم الذي أعطيته للمنفذ (sonar rename)، ثم اسم الخدمة، ثم ما تم اكتشافه.

الأعمدة المتاحة: port، process، pid، type، url، group، cpu، mem، threads، uptime، state، connections، health، latency، container، image، containerport، compose، project، user، bind، ip.

تطبيقات سطح المكتب وخدمات النظام التي تصادف أنها تستمع — Figma، Discord، Spotify، ControlCenter، حزم .app في macOS، خدمات /System/Library/ — تكون مخفية ما لم تمرر -a.

sonar start

ابدأ مشروعًا من ملف 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`

في المقدمة، يبدأ sonar الخدمات عبر الخدمة الخلفية (daemon)، ويتابع سجلاتها مع اسم الخدمة أمام كل سطر، وعندما تضغط على Ctrl+C يوقف الخدمات التي بدأها. أما الخدمة التي كانت تعمل بالفعل فيُتركها دون مساس، ويعود sonar من تلقاء نفسه بمجرد انتهاء كل خدمة بدأها.

تسمّي الوسائط قبل -- دليلاً أو خدمات؛ وكل ما يأتي بعد -- هو أمر. أو شغّل أمراً واحداً كخدمة مُسمّاة ضمن مجموعة:

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

لا شيء يجب تمريره:

  • Group — --group، وإلا فإن name في أقرب sonar.yaml، وإلا فإن اسم دليل جذر git (تصبح worktree repo@worktree)، وإلا فإن اسم الدليل الحالي.
  • Name — --name، وإلا فإن خدمة sonar.yaml التي يطابق cmd الخاص بها، وإلا فإنه يُستنتج من الأمر (npm run dev → dev، uv run api → api، python -m uvicorn → uvicorn، ./dev.sh → dev.sh).
  • Port — --port هو تلميح، وليس ارتباطًا: يظهر التشغيل كـ starting حتى يصبح المنفذ في حالة استماع فعليًا، ويستخدمه الخادم لمطابقة العملية بالمنفذ.

يرث العملية الفرعية stdin وstdout وstderr وcwd والبيئة، بالإضافة إلى SONAR_GROUP وSONAR_NAME وSONAR_RUN_ID. ويحصل على مجموعة عمليات خاصة به، لذا فإن sonar kill يُسقط الشجرة بأكملها — خادم تطوير مع مراقبيه وعماله. يتم تمرير Ctrl+C، ويخرج sonar برمز خروج العملية الفرعية.

يعود --detach فورًا ويكتب المخرجات إلى ~/.config/sonar/logs/<group>/<name>.log. يعرض --list ما بدأه sonar، وتحته ما انتهى منذ ذلك الحين — مع رمز الخروج، وما إذا كان قد تعطل أو تم إيقافه (--json للصيغة القابلة للقراءة آليًا):

sonar start --list
sonar start --detach --name demo --port 8123 -- sleep 5
sonar start --list --json
# check

sonar.yaml

يُعرِّف المشروع نفسه وخدماته في ملف sonar.yaml في جذر المستودع. وهو اختياري — إذ يقوم sonar بالتجميع حسب جذر git بدونه — والغرض منه أن يتم الالتزام به:

الفئات