diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml
new file mode 100644
index 0000000..b7d44ef
--- /dev/null
+++ b/.github/workflows/docker-publish.yml
@@ -0,0 +1,32 @@
+name: Docker Publish (GHCR)
+on:
+ release:
+ types: [published]
+permissions:
+ contents: read
+ packages: write
+jobs:
+ publish:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: docker/setup-buildx-action@v3
+ - uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+ - uses: docker/metadata-action@v5
+ id: meta
+ with:
+ images: ghcr.io/${{ github.repository }}
+ tags: |
+ type=semver,pattern={{version}}
+ type=semver,pattern={{major}}.{{minor}}
+ type=raw,value=latest
+ - uses: docker/build-push-action@v5
+ with:
+ context: .
+ push: true
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml
new file mode 100644
index 0000000..7e995a7
--- /dev/null
+++ b/.github/workflows/pypi-publish.yml
@@ -0,0 +1,21 @@
+name: PyPI Publish
+on:
+ release:
+ types: [published]
+permissions:
+ contents: read
+ id-token: write
+jobs:
+ publish:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v5
+ with:
+ python-version: '3.11'
+ - name: Install build tools
+ run: pip install build
+ - name: Build package
+ run: python -m build
+ - name: Publish to PyPI
+ uses: pypa/gh-action-pypi-publish@release/v1
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..991beeb
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,19 @@
+name: Release
+on:
+ push:
+ tags:
+ - 'v*'
+permissions:
+ contents: write
+jobs:
+ release:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - name: Create GitHub Release
+ uses: softprops/action-gh-release@v2
+ with:
+ generate_release_notes: true
+ fail_on_unmatched_files: false
diff --git a/README.md b/README.md
index 6ce81c7..81f3d64 100644
--- a/README.md
+++ b/README.md
@@ -4,14 +4,16 @@
# TeleOps
-**A unified NOC platform for Telegram — monitor agents, discover SNMP devices, run a live dashboard, and manage Linux and Windows hosts from chat commands.**
+**Unified NOC platform for Telegram — monitor agents, discover SNMP devices, run a live dashboard, and manage Linux and Windows hosts from chat commands**
-
-
-
-
-
-
+[](https://github.com/OneByJorah/TeleOps/releases)
+[](https://pypi.org/project/teleops/)
+[](https://www.docker.com/)
+[](https://www.python.org/downloads/)
+[](https://flask-socketio.readthedocs.io/)
+[](https://telegram.org/)
+[](https://en.wikipedia.org/wiki/Simple_Network_Management_Protocol)
+[](https://opensource.org/licenses/MIT)
@@ -21,123 +23,119 @@
TeleOps turns Telegram into a network operations console. A bot fronts a set of cross-platform agents, an SNMP discovery engine, and a live web dashboard, so you can check host health, run signed commands, and get threshold alerts without opening a terminal or a monitoring portal.
-It is built for small NOC and homelab operators who want lightweight, self-hosted infrastructure monitoring that reaches them where they already are — chat.
+Built for small NOC and homelab operators who want lightweight, self-hosted infrastructure monitoring that reaches them where they already are — chat.
## Quick Start
+### pip
+
+```bash
+pip install teleops
+```
+
+### Docker (recommended)
+
```bash
git clone https://github.com/OneByJorah/TeleOps.git
cd TeleOps
-
cp .env.example .env # set TELEGRAM_BOT_TOKEN and ADMIN_CHAT_IDS
docker compose up -d
```
Open **http://localhost:5000** for the dashboard. The agent server listens on **http://localhost:8080**.
-> [!WARNING]
-> The `bot` service needs a valid Telegram token to stay up. Check `docker logs netbot` after editing `.env`. On first run the entrypoint seeds `config/config.yaml` from `.env`.
+### From Source
-## Features
+```bash
+git clone https://github.com/OneByJorah/TeleOps.git
+cd TeleOps
+pip install -r requirements.txt
+cp .env.example .env
+python3 bot.py
+```
-- **Telegram control plane** — admin-gated commands for status, agents, SNMP, and per-host actions.
-- **Cross-platform agents** — a stdlib Linux agent and a PowerShell 5.1 Windows agent with HMAC-SHA256 signed command dispatch.
-- **SNMP discovery** — automated device discovery and polling over SNMP v1/v2c/v3.
-- **Live dashboard** — Flask + SocketIO API with REST polling fallback.
-- **Alert management** — CPU/memory/disk thresholds, cooldown, and agent offline detection.
-- **Agent server** — self-registration, heartbeat, and installer downloads over HTTP.
-- **Windows host management** — AD, DNS, and DHCP actions from the Windows agent.
-- **Redis-backed state** — durable job/state storage with append-only persistence.
+## Install
-## Architecture
+### pip
+```bash
+pip install teleops
```
-Telegram Admin ──commands──▶ NetBot ──HMAC-signed commands──▶ Agents (Linux/Windows)
- │
- NetworkScanner ──────────▶│ probes http://:7845/info
- SNMPScanner ──────────────▶│ polls v2c communities
- ▼
- Agent Server (:8080) · Dashboard (:5000) · Alerts → Telegram
+
+### Docker
+
+```bash
+git clone https://github.com/OneByJorah/TeleOps.git
+cd TeleOps
+cp .env.example .env
+docker compose up -d
```
-Agents register themselves (`POST /agent/register`) or are discovered by subnet scan, report heartbeats every 25 s, and execute signed commands (`stats`, `services`, `firewall`, `docker_ps`, AD/DNS/DHCP on Windows, `cmd` on Linux).
+### From Source
-## Configuration
+```bash
+git clone https://github.com/OneByJorah/TeleOps.git
+cd TeleOps
+pip install -r requirements.txt
+cp .env.example .env
+python3 bot.py
+```
+
+## Features
-Primary configuration lives in **`config/config.yaml`** (copy from `config/config.yaml.example`): discovery networks, SNMP communities, alert thresholds, and heartbeat intervals all live there. Environment variables are read by `bot/main.py` and seeded into YAML by the entrypoint.
-
-| Variable | Default | Description |
-|----------|---------|-------------|
-| `TELEGRAM_BOT_TOKEN` | *(empty)* | Bot token from BotFather (overrides YAML) |
-| `ADMIN_CHAT_IDS` | *(empty)* | Comma-separated Telegram user IDs with admin access |
-| `SECRET_KEY` | *(empty)* | HMAC secret shared with agents (overrides YAML) |
-| `REDIS_HOST` / `REDIS_PORT` | `redis` / `6379` | Redis connection |
-| `REDIS_PASSWORD` | *(generated)* | Redis auth password |
-| `DASHBOARD_PORT` | `5000` | Web dashboard port |
-| `AGENT_PORT` | `8080` | Agent server port |
-| `SNMP_COMMUNITY` | `public` | Default SNMP community |
-| `SCAN_INTERVAL_MINUTES` | `60` | Network discovery interval |
-
-## Telegram Commands
-
-| Command | Description |
-|---------|-------------|
-| `/start` | Initialize the bot (admin menu) |
-| `/status` | Agent & SNMP device status overview |
-| `/agents` | List registered agents |
-| `/dashboard` | Get dashboard URL |
-| `/win [action]` | Windows agent menu or action |
-| `/lx [action]` | Linux agent menu or action |
-| `/snmp list\|scan\|` | SNMP devices, scan, or poll one device |
-| `/alert` | Alert configuration info |
-
-## API & Endpoints
-
-| Endpoint | Method | Description |
-|----------|--------|-------------|
-| `/` | GET | Dashboard UI |
-| `/api/agents` | GET | Registered agents |
-| `/api/snmp` | GET | Discovered SNMP devices |
-| `/api/summary` | GET | Aggregated status summary |
-| `/agent/register` | POST | Agent self-registration |
-| `/agent/download/linux` | GET | Linux agent installer script |
-| `/agent/download/windows` | GET | Windows agent installer script |
-| `/install/linux` | GET | Linux install helper |
-| `/install/windows` | GET | Windows install helper |
-| `/health` | GET | Agent server health |
-
-## Use Cases
-
-1. **Homelab operators** — monitor a mixed Linux/Windows fleet from Telegram.
-2. **Small NOCs** — combine agent metrics and SNMP devices in one dashboard.
-3. **Remote admins** — run signed host commands without a VPN into a jump box.
+- **Telegram control plane** — admin-gated commands for status, agents, SNMP, and per-host actions
+- **Cross-platform agents** — stdlib Linux agent and PowerShell 5.1 Windows agent with HMAC-SHA256 signed command dispatch
+- **SNMP discovery** — automated device discovery and polling over SNMP v1/v2c/v3
+- **Live dashboard** — Flask + SocketIO API with REST polling fallback
+- **Alert management** — CPU/memory/disk thresholds, configurable alert routing
+- **Self-hosted** — no external dependencies, no cloud required
+- **Docker support** — run with `docker compose up -d`
## Tech Stack
-Python 3.10+, python-telegram-bot, aiohttp, Flask + Flask-SocketIO, pysnmp, Redis, SQLAlchemy, PowerShell (Windows agent), Docker Compose.
+- **Backend** — Python 3.10+, Flask, Flask-SocketIO, Eventlet
+- **Telegram** — python-telegram-bot 20+
+- **SNMP** — pysnmp 4.4+
+- **Agents** — stdlib (Linux), PowerShell 5.1 (Windows), HMAC-SHA256 signed commands
+- **Deployment** — Docker Compose, pip install
+- **Config** — YAML (`config/config.yaml`), environment variables (`.env`)
-## Screenshots
+## Package Badges
-| Dashboard | Overview |
-|---|---|
-|  |  |
+[](https://github.com/OneByJorah/TeleOps/releases)
+[](https://pypi.org/project/teleops/)
+[](https://www.docker.com/)
+[](https://opensource.org/licenses/MIT)
-More captures live in [`docs/screenshots/`](docs/screenshots/).
+## Configuration
-## Security
+Copy `.env.example` to `.env` and configure:
-Agent `/command` endpoints require HMAC-SHA256 signatures over `timestamp:body` with a ±5-minute freshness window. The dashboard and agent server expose operational data without authentication — do not expose ports 5000/8080 to untrusted networks. See [SECURITY.md](SECURITY.md).
+| Variable | Description |
+|----------|-------------|
+| `TELEGRAM_BOT_TOKEN` | Telegram bot token (required) |
+| `ADMIN_CHAT_IDS` | Comma-separated admin chat IDs (required) |
+| `FLASK_PORT` | Dashboard port (default: 5000) |
+| `AGENT_PORT` | Agent server port (default: 8080) |
+
+The `bot` service seeds `config/config.yaml` from `.env` on first run.
+
+## Architecture
+
+```
+Telegram Bot ──▶ Bot Service (bot.py)
+ │
+ ├──▶ Agent Server (agents/server.py) ──▶ Linux/Windows Agents
+ │
+ ├──▶ SNMP Discovery (snmp/discover.py)
+ │
+ └──▶ Dashboard (dashboard/app.py) ──▶ Flask + SocketIO
+```
## Contributing
-Contributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md). [Open an issue](https://github.com/OneByJorah/TeleOps/issues) to report a bug or request a feature.
+Contributions are welcome. [Open an issue](https://github.com/OneByJorah/TeleOps/issues) to report a bug or request a feature.
## License
MIT — see [LICENSE](LICENSE).
-
-## Connect
-
-- [jorahone.com](https://jorahone.com)
-- [GitHub Org](https://github.com/OneByJorah)
-- [info@jorahone.com](mailto:info@jorahone.com)
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..9156c1f
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,47 @@
+[build-system]
+requires = ["setuptools>=61.0", "wheel"]
+build-backend = "setuptools.build_meta"
+
+[project]
+name = "teleops"
+version = "1.0.0"
+description = "A unified NOC platform for Telegram — monitor agents, discover SNMP devices, run a live dashboard, and manage Linux and Windows hosts from chat commands."
+readme = "README.md"
+license = {text = "MIT"}
+authors = [{name = "OneByJorah", email = "info@jorahone.com"}]
+keywords = ["telegram", "noc", "monitoring", "snmp", "network-operations", "flask", "socketio", "dashboard", "chatops", "self-hosted", "linux", "windows", "jorahone"]
+classifiers = [
+ "Development Status :: 4 - Beta",
+ "Environment :: Web Environment",
+ "Intended Audience :: System Administrators",
+ "License :: OSI Approved :: MIT License",
+ "Operating System :: OS Independent",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.10",
+ "Programming Language :: Python :: 3.11",
+ "Programming Language :: Python :: 3.12",
+ "Topic :: System :: Systems Administration",
+ "Topic :: Communications :: Chat",
+ "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
+]
+requires-python = ">=3.10"
+dependencies = [
+ "flask>=3.0",
+ "flask-socketio>=5.0",
+ "eventlet>=0.34",
+ "requests>=2.31",
+ "python-telegram-bot>=20.0",
+ "pysnmp>=4.4",
+ "pyyaml>=6.0",
+]
+
+[project.optional-dependencies]
+dev = ["pytest", "black", "flake8"]
+
+[project.urls]
+Homepage = "https://github.com/OneByJorah/TeleOps"
+Repository = "https://github.com/OneByJorah/TeleOps"
+Issues = "https://github.com/OneByJorah/TeleOps/issues"
+
+[tool.setuptools.packages.find]
+include = ["teleops*"]