pinghue 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. pinghue-0.1.0/.github/workflows/ci.yml +44 -0
  2. pinghue-0.1.0/.github/workflows/publish.yml +52 -0
  3. pinghue-0.1.0/CHANGELOG.md +16 -0
  4. pinghue-0.1.0/CODE_OF_CONDUCT.md +14 -0
  5. pinghue-0.1.0/CONTRIBUTING.md +50 -0
  6. pinghue-0.1.0/LICENSE +21 -0
  7. pinghue-0.1.0/MANIFEST.in +15 -0
  8. pinghue-0.1.0/PKG-INFO +315 -0
  9. pinghue-0.1.0/README.md +276 -0
  10. pinghue-0.1.0/SECURITY.md +40 -0
  11. pinghue-0.1.0/docs/assets/pinghue-demo.svg +72 -0
  12. pinghue-0.1.0/docs/assets/pinghue-hero.svg +79 -0
  13. pinghue-0.1.0/docs/release-checklist.md +61 -0
  14. pinghue-0.1.0/docs/repository-hardening.md +54 -0
  15. pinghue-0.1.0/examples/pinghue-output-example.json +43 -0
  16. pinghue-0.1.0/packaging/homebrew/pinghue.rb +65 -0
  17. pinghue-0.1.0/pinghue-threat-model.md +165 -0
  18. pinghue-0.1.0/pyproject.toml +76 -0
  19. pinghue-0.1.0/schemas/output-v1.schema.json +207 -0
  20. pinghue-0.1.0/scripts/apply-github-hardening.sh +59 -0
  21. pinghue-0.1.0/security-best-practices-report.md +58 -0
  22. pinghue-0.1.0/setup.cfg +4 -0
  23. pinghue-0.1.0/src/pinghue/__init__.py +3 -0
  24. pinghue-0.1.0/src/pinghue/app.py +284 -0
  25. pinghue-0.1.0/src/pinghue/cli.py +177 -0
  26. pinghue-0.1.0/src/pinghue/display.py +15 -0
  27. pinghue-0.1.0/src/pinghue/doctor.py +268 -0
  28. pinghue-0.1.0/src/pinghue/export.py +83 -0
  29. pinghue-0.1.0/src/pinghue/history.py +49 -0
  30. pinghue-0.1.0/src/pinghue/hostfile.py +19 -0
  31. pinghue-0.1.0/src/pinghue/models.py +149 -0
  32. pinghue-0.1.0/src/pinghue/probes.py +191 -0
  33. pinghue-0.1.0/src/pinghue/py.typed +1 -0
  34. pinghue-0.1.0/src/pinghue/runner.py +231 -0
  35. pinghue-0.1.0/src/pinghue/ui.py +421 -0
  36. pinghue-0.1.0/src/pinghue.egg-info/PKG-INFO +315 -0
  37. pinghue-0.1.0/src/pinghue.egg-info/SOURCES.txt +49 -0
  38. pinghue-0.1.0/src/pinghue.egg-info/dependency_links.txt +1 -0
  39. pinghue-0.1.0/src/pinghue.egg-info/entry_points.txt +2 -0
  40. pinghue-0.1.0/src/pinghue.egg-info/requires.txt +11 -0
  41. pinghue-0.1.0/src/pinghue.egg-info/top_level.txt +1 -0
  42. pinghue-0.1.0/tests/test_cli.py +35 -0
  43. pinghue-0.1.0/tests/test_display_safety.py +44 -0
  44. pinghue-0.1.0/tests/test_doctor.py +53 -0
  45. pinghue-0.1.0/tests/test_export.py +80 -0
  46. pinghue-0.1.0/tests/test_history.py +41 -0
  47. pinghue-0.1.0/tests/test_hostfile.py +20 -0
  48. pinghue-0.1.0/tests/test_models.py +65 -0
  49. pinghue-0.1.0/tests/test_probes.py +76 -0
  50. pinghue-0.1.0/tests/test_scheduler.py +42 -0
  51. pinghue-0.1.0/tests/test_ui.py +333 -0
@@ -0,0 +1,44 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches:
7
+ - main
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ test:
14
+ name: ${{ matrix.os }} / Python ${{ matrix.python-version }}
15
+ runs-on: ${{ matrix.os }}
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ os:
20
+ - ubuntu-latest
21
+ - macos-latest
22
+ python-version:
23
+ - "3.10"
24
+ - "3.11"
25
+ - "3.12"
26
+ steps:
27
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
28
+ with:
29
+ persist-credentials: false
30
+ - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
31
+ with:
32
+ python-version: ${{ matrix.python-version }}
33
+ - name: Install package
34
+ run: python -m pip install -e ".[dev]"
35
+ - name: Ruff
36
+ run: ruff check .
37
+ - name: Mypy
38
+ run: mypy src
39
+ - name: Tests
40
+ run: pytest
41
+ - name: Build
42
+ run: python -m build
43
+ - name: Check package
44
+ run: twine check dist/*
@@ -0,0 +1,52 @@
1
+ name: Publish
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*.*.*"
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ build:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
16
+ with:
17
+ persist-credentials: false
18
+ - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
19
+ with:
20
+ python-version: "3.12"
21
+ - name: Install build tooling
22
+ run: python -m pip install build==1.5.0 setuptools==82.0.1 twine==6.2.0 wheel==0.47.0
23
+ - name: Build
24
+ run: python -m build --no-isolation
25
+ - name: Check package
26
+ run: twine check dist/*
27
+ - name: Upload distributions
28
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
29
+ with:
30
+ name: dist
31
+ path: dist/*
32
+ if-no-files-found: error
33
+
34
+ publish:
35
+ runs-on: ubuntu-latest
36
+ needs: build
37
+ environment: pypi
38
+ permissions:
39
+ contents: write
40
+ id-token: write
41
+ steps:
42
+ - name: Download distributions
43
+ uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
44
+ with:
45
+ name: dist
46
+ path: dist
47
+ - name: Publish to PyPI
48
+ uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
49
+ - name: Create GitHub release
50
+ uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3
51
+ with:
52
+ files: dist/*
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here.
4
+
5
+ This project follows semantic versioning once it reaches `1.0.0`. Before `1.0.0`, CLI flags and JSON output may change; breaking JSON changes increment `schema_version`.
6
+
7
+ ## 0.1.0 - 2026-05-14
8
+
9
+ - Initial public release candidate.
10
+ - Added concurrent ICMP and TCP probing.
11
+ - Added Textual TUI with Slate + Signal colors.
12
+ - Added no-TUI mode for scripting and package smoke tests.
13
+ - Added `--check` environment doctor for macOS/Linux ICMP readiness.
14
+ - Added schema-versioned JSON export.
15
+ - Added terminal display sanitization for operator-visible target and error text.
16
+ - Added pinned GitHub Actions release workflow for PyPI trusted publishing.
@@ -0,0 +1,14 @@
1
+ # Code of Conduct
2
+
3
+ This project expects professional, respectful collaboration.
4
+
5
+ ## Expected Behavior
6
+
7
+ - Be direct and constructive.
8
+ - Keep technical discussions focused on evidence and maintainability.
9
+ - Respect maintainer time.
10
+ - Avoid harassment, insults, and personal attacks.
11
+
12
+ ## Reporting
13
+
14
+ Report conduct issues through the repository maintainers. If the issue is security-sensitive, use the process in `SECURITY.md`.
@@ -0,0 +1,50 @@
1
+ # Contributing
2
+
3
+ ## Development Setup
4
+
5
+ ```sh
6
+ python -m venv .venv
7
+ . .venv/bin/activate
8
+ python -m pip install -e ".[dev]"
9
+ pytest
10
+ ruff check .
11
+ mypy src
12
+ ```
13
+
14
+ ## Commit and PR Policy
15
+
16
+ - Work on branches named with conventional prefixes such as `feat/`, `fix/`, `docs/`, `ci/`, or `release/`.
17
+ - Submit changes through pull requests.
18
+ - Keep commits signed and verified.
19
+ - Keep changes focused; avoid unrelated refactors.
20
+ - Include tests for behavior changes.
21
+ - Update README, schema examples, or release docs when user-facing behavior changes.
22
+
23
+ Useful local defaults:
24
+
25
+ ```sh
26
+ git config commit.gpgsign true
27
+ git config tag.gpgsign true
28
+ git config gpg.format ssh
29
+ ```
30
+
31
+ ## Required Checks Before Merge
32
+
33
+ ```sh
34
+ pytest
35
+ ruff check .
36
+ mypy src
37
+ python -m build
38
+ twine check dist/*
39
+ ```
40
+
41
+ ## Release Policy
42
+
43
+ Releases are tag-driven. The publish workflow requires:
44
+
45
+ - a signed release tag
46
+ - GitHub Actions CI passing
47
+ - PyPI trusted publishing configured for `inxbit/pinghue`
48
+ - a protected `pypi` GitHub environment
49
+
50
+ See `docs/release-checklist.md`.
pinghue-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 inxbit
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,15 @@
1
+ include README.md
2
+ include LICENSE
3
+ include CHANGELOG.md
4
+ include SECURITY.md
5
+ include CONTRIBUTING.md
6
+ include CODE_OF_CONDUCT.md
7
+ include pinghue-threat-model.md
8
+ include security-best-practices-report.md
9
+ recursive-include schemas *.json
10
+ recursive-include examples *.json
11
+ recursive-include docs *.md *.svg
12
+ recursive-include packaging *.rb
13
+ recursive-include scripts *.sh
14
+ recursive-include tests *.py
15
+ recursive-include .github/workflows *.yml
pinghue-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,315 @@
1
+ Metadata-Version: 2.4
2
+ Name: pinghue
3
+ Version: 0.1.0
4
+ Summary: Colored, concurrent ICMP/TCP ping monitor for the terminal
5
+ Author: inxbit
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/inxbit/pinghue
8
+ Project-URL: Repository, https://github.com/inxbit/pinghue
9
+ Project-URL: Issues, https://github.com/inxbit/pinghue/issues
10
+ Project-URL: Changelog, https://github.com/inxbit/pinghue/blob/main/CHANGELOG.md
11
+ Project-URL: Security, https://github.com/inxbit/pinghue/security
12
+ Keywords: ping,icmp,tcp,monitoring,tui,network
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: System Administrators
16
+ Classifier: Operating System :: MacOS
17
+ Classifier: Operating System :: POSIX :: Linux
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Topic :: System :: Monitoring
23
+ Classifier: Topic :: System :: Networking :: Monitoring
24
+ Classifier: Topic :: Utilities
25
+ Requires-Python: >=3.10
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: icmplib<4,>=3.0.4
29
+ Requires-Dist: textual~=8.2.0
30
+ Provides-Extra: dev
31
+ Requires-Dist: build>=1.2; extra == "dev"
32
+ Requires-Dist: jsonschema>=4.22; extra == "dev"
33
+ Requires-Dist: mypy>=1.10; extra == "dev"
34
+ Requires-Dist: pytest>=8.2; extra == "dev"
35
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
36
+ Requires-Dist: ruff>=0.5; extra == "dev"
37
+ Requires-Dist: twine>=5.1; extra == "dev"
38
+ Dynamic: license-file
39
+
40
+ # pinghue
41
+
42
+ <p align="center">
43
+ <img src="https://raw.githubusercontent.com/inxbit/pinghue/main/docs/assets/pinghue-hero.svg" alt="pinghue - terminal ping monitor for maintenance windows" width="920">
44
+ </p>
45
+
46
+ <p align="center">
47
+ <a href="https://pypi.org/project/pinghue/"><img alt="PyPI" src="https://img.shields.io/pypi/v/pinghue?color=58a6ff"></a>
48
+ <a href="https://pypi.org/project/pinghue/"><img alt="Python versions" src="https://img.shields.io/pypi/pyversions/pinghue?color=7ee787"></a>
49
+ <a href="https://github.com/inxbit/pinghue/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/inxbit/pinghue/actions/workflows/ci.yml/badge.svg"></a>
50
+ <a href="https://github.com/inxbit/pinghue/blob/main/LICENSE"><img alt="License" src="https://img.shields.io/github/license/inxbit/pinghue?color=f2cc60"></a>
51
+ </p>
52
+
53
+ `pinghue` is a colored, concurrent ICMP/TCP ping monitor for maintenance windows. It gives operators a dense terminal view for many hosts at once and can also write structured JSON for reports, cron jobs, and CI checks.
54
+
55
+ Current version: `0.1.0`.
56
+
57
+ This is pre-1.0 software. CLI flags and JSON output may change before `1.0.0`; breaking JSON changes increment `schema_version`.
58
+
59
+ <p align="center">
60
+ <img src="https://raw.githubusercontent.com/inxbit/pinghue/main/docs/assets/pinghue-demo.svg" alt="animated pinghue terminal demo" width="920">
61
+ </p>
62
+
63
+ ## What This Is
64
+
65
+ - A focused terminal monitor for maintenance windows, migrations, and quick reachability checks.
66
+ - A concurrent ICMP/TCP probe runner with a readable Textual TUI.
67
+ - A scriptable probe tool with `--no-tui`, `--count`, `--duration`, and `--output`.
68
+ - A JSON-producing report helper for post-maintenance evidence.
69
+ - A local operator tool designed for macOS and Linux.
70
+
71
+ ## What This Is Not
72
+
73
+ - Not a Prometheus, Smokeping, Zabbix, or NMS replacement.
74
+ - Not a long-running metrics database or alerting system.
75
+ - Not a privileged daemon.
76
+ - Not a packet capture or traceroute tool.
77
+ - Not a service that accepts remote network requests.
78
+
79
+ ## Install
80
+
81
+ Recommended isolated installs:
82
+
83
+ ```sh
84
+ uv tool install pinghue
85
+ ```
86
+
87
+ or:
88
+
89
+ ```sh
90
+ pipx install pinghue
91
+ ```
92
+
93
+ Plain pip also works inside a virtual environment:
94
+
95
+ ```sh
96
+ python -m pip install pinghue
97
+ ```
98
+
99
+ Install the current development tree:
100
+
101
+ ```sh
102
+ python -m pip install -e ".[dev]"
103
+ ```
104
+
105
+ Homebrew support is planned through `inxbit/tap` after the first PyPI sdist is published.
106
+
107
+ ## Quick Start
108
+
109
+ ```sh
110
+ pinghue 1.1.1.1 8.8.8.8 example.com
111
+ pinghue -f hosts.txt
112
+ pinghue -p 443 example.com
113
+ pinghue -p 1 127.0.0.1 -c 1 --no-tui
114
+ pinghue --output maintenance.json 1.1.1.1 example.com
115
+ ```
116
+
117
+ Host files are plain text. Blank lines and lines starting with `#` are ignored.
118
+
119
+ ```text
120
+ # edge and core checks
121
+ 1.1.1.1
122
+ 8.8.8.8
123
+ example.com
124
+ internal-db.corp
125
+ ```
126
+
127
+ ## Modes
128
+
129
+ `pinghue` defaults to ICMP mode:
130
+
131
+ ```sh
132
+ pinghue 1.1.1.1 example.com
133
+ ```
134
+
135
+ TCP mode is enabled by passing a port:
136
+
137
+ ```sh
138
+ pinghue -p 443 example.com api.internal
139
+ ```
140
+
141
+ Use no-TUI mode for scripts, cron, CI, and package smoke tests:
142
+
143
+ ```sh
144
+ pinghue -p 443 example.com -c 3 --no-tui
145
+ ```
146
+
147
+ Example no-TUI output:
148
+
149
+ ```text
150
+ 2026-05-14T18:32:11.420000+00:00 1.1.1.1 ok latency=9.20ms
151
+ 2026-05-14T18:32:11.421000+00:00 example.com ok latency=14.08ms
152
+ 2026-05-14T18:32:12.420000+00:00 api.internal timeout latency=-
153
+ ```
154
+
155
+ ## CLI Reference
156
+
157
+ ```text
158
+ pinghue [OPTIONS] [TARGET ...]
159
+ ```
160
+
161
+ | Option | Default | Description |
162
+ | --- | --- | --- |
163
+ | `TARGET ...` | none | Hostnames or IP addresses to probe. Required unless `--check` is used. |
164
+ | `-f, --file PATH` | none | Read targets from a plain-text host file. Blank lines and `#` comments are ignored. |
165
+ | `-p, --port PORT` | ICMP | Enable TCP connect checks against `PORT`. Valid range: `1-65535`. |
166
+ | `-4, --ipv4` | off | Force IPv4 resolution/probing. |
167
+ | `-6, --ipv6` | off | Force IPv6 resolution/probing. |
168
+ | `-n, --numeric` | off | Skip DNS and require IP literals. |
169
+ | `-i, --interval SEC` | `1.0` | Seconds between probes. Minimum: `0.1`. |
170
+ | `--timeout SEC` | interval | Per-probe timeout in seconds. Must be greater than `0`. |
171
+ | `-c, --count N` | continuous | Stop after `N` probes per target. |
172
+ | `--duration SEC` | continuous | Stop after elapsed seconds. |
173
+ | `--no-tui` | off | Print one line per probe instead of launching the TUI. |
174
+ | `--output PATH` | none | Write a JSON run summary on exit. |
175
+ | `--no-samples` | off | Omit per-probe samples from JSON output. |
176
+ | `--concurrency N` | `64` | Maximum concurrent probes. |
177
+ | `--jitter-threshold MS` | `50.0` | Mark jitter as attention-worthy above this standard deviation. |
178
+ | `--fail-threshold COUNT` | `3` | Classify a host as down after this many consecutive failed probes. |
179
+ | `--history-style STYLE` | `bar` | One of `bar`, `dots`, `sparkline`, or `none`. |
180
+ | `--check` | off | Run the environment doctor and exit. |
181
+ | `--quiet` | off | With `--check`, suppress output and use only the exit code. |
182
+ | `-v, --version` | none | Print the installed version. |
183
+ | `-h, --help` | none | Print help. |
184
+
185
+ ## TUI Controls
186
+
187
+ | Key | Action |
188
+ | --- | --- |
189
+ | `q` | Quit. |
190
+ | `a` | Show or hide resolved addresses. |
191
+ | `r` | Reset the selected host. |
192
+ | `R` | Reset all hosts. |
193
+ | `b` | Probe the selected host immediately. |
194
+ | `B` | Probe all hosts immediately. |
195
+
196
+ ## History Legend
197
+
198
+ The default history style is a fixed-scale colored bar:
199
+
200
+ - Green bar: successful probe.
201
+ - Amber bar: successful probe at or above the slow-latency threshold.
202
+ - Red `.` / `·`: timeout, loss, or down state.
203
+ - Amber `!`: TCP refused.
204
+
205
+ Successful latency uses `▁▂▃▄▅▆▇█`.
206
+
207
+ The fixed mapping keeps rows comparable:
208
+
209
+ | Latency | Glyph |
210
+ | --- | --- |
211
+ | `<=1ms` | `▁` |
212
+ | `<=3ms` | `▂` |
213
+ | `<=10ms` | `▃` |
214
+ | `<=30ms` | `▄` |
215
+ | `<=100ms` | `▅` |
216
+ | `<=300ms` | `▆` |
217
+ | `<=1000ms` | `▇` |
218
+ | `>1000ms` | `█` |
219
+
220
+ Use `--history-style dots`, `--history-style sparkline`, or `--history-style none` when a terminal font or workflow needs a simpler display.
221
+
222
+ ## Doctor
223
+
224
+ Run the doctor before relying on ICMP mode:
225
+
226
+ ```sh
227
+ pinghue --check
228
+ ```
229
+
230
+ Linux may block unprivileged ICMP sockets. TCP mode does not need special privileges:
231
+
232
+ ```sh
233
+ pinghue -p 443 example.com
234
+ ```
235
+
236
+ If `pinghue --check` reports that your GID is outside `net.ipv4.ping_group_range`, the preferred fix is:
237
+
238
+ ```sh
239
+ sudo sysctl -w net.ipv4.ping_group_range="0 2147483647"
240
+ echo 'net.ipv4.ping_group_range=0 2147483647' \
241
+ | sudo tee /etc/sysctl.d/99-pinghue.conf
242
+ ```
243
+
244
+ The capability alternative is available but must be re-applied after binary upgrades:
245
+
246
+ ```sh
247
+ sudo setcap cap_net_raw+ep "$(command -v pinghue)"
248
+ ```
249
+
250
+ Do not set capabilities on a shared Python interpreter.
251
+
252
+ ## JSON Output
253
+
254
+ `--output PATH` writes one JSON document per run. The schema lives at `schemas/output-v1.schema.json`, and an example lives at `examples/pinghue-output-example.json`.
255
+
256
+ ```sh
257
+ pinghue -f hosts.txt --duration 180 --output maintenance.json
258
+ ```
259
+
260
+ Use `--no-samples` when you only need final per-target statistics.
261
+
262
+ Every output document includes:
263
+
264
+ - `schema_version`
265
+ - `pinghue_version`
266
+ - run metadata
267
+ - probe configuration
268
+ - ordered target results
269
+ - per-target stats
270
+ - optional per-probe samples
271
+
272
+ ## Security Model
273
+
274
+ `pinghue` is a local CLI/TUI. It does not run a server, accept remote requests, store credentials, or require secrets. The security-sensitive areas are:
275
+
276
+ - terminal rendering of operator-supplied hostnames and OS error strings
277
+ - Linux ICMP privilege configuration
278
+ - local output paths selected by the operator
279
+ - release workflow integrity
280
+
281
+ See `pinghue-threat-model.md`, `security-best-practices-report.md`, and `SECURITY.md`.
282
+
283
+ ## Release Channels
284
+
285
+ Planned release path for `0.1.0`:
286
+
287
+ 1. GitHub repository: `inxbit/pinghue`
288
+ 2. GitHub Actions CI on Linux and macOS
289
+ 3. GitHub Release with sdist and wheel artifacts
290
+ 4. PyPI trusted publishing through a protected `pypi` environment
291
+ 5. Homebrew formula generation after the PyPI sdist exists
292
+
293
+ The release workflow is tag-driven:
294
+
295
+ ```sh
296
+ git tag -s v0.1.0 -m "Release v0.1.0"
297
+ git push origin v0.1.0
298
+ ```
299
+
300
+ ## Development
301
+
302
+ ```sh
303
+ python -m venv .venv
304
+ . .venv/bin/activate
305
+ python -m pip install -e ".[dev]"
306
+ pytest
307
+ ruff check .
308
+ mypy src
309
+ python -m build
310
+ twine check dist/*
311
+ ```
312
+
313
+ ## License
314
+
315
+ MIT. See `LICENSE`.