diff --git a/.gitignore b/.gitignore index a728683..c0b1b36 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,6 @@ tickets/done/*.md # Python __pycache__/ *.pyc + +# host-specific ogmactl extension (operator-provided, never published) +bin/ogmactl.local diff --git a/CHANGELOG.md b/CHANGELOG.md index f0c2331..757bb5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,15 @@ All notable changes to this project are documented here. The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project aims to follow [Semantic Versioning](https://semver.org/). +## [1.0.2] — 2026-06-17 + +### Added +- **Host-local `ogmactl` extensions.** `ogmactl` now delegates any subcommand it doesn't recognise + to an optional, executable `bin/ogmactl.local` (gitignored), letting operators add host-specific + commands without forking the host-agnostic tool. On a stock install there's no such file and + unknown commands are refused exactly as before, so the bot's whitelist boundary is unchanged. + Documented in the README; `bin/ogmactl.local` is gitignored. + ## [1.0.1] — 2026-06-17 ### Fixed @@ -132,6 +141,7 @@ First public release. A minimal, self-hosted bridge from Telegram to Claude Code - Single shared brain — multiple allow-listed chats share one persona/workspace/memory. Per-user isolation is planned (see issues). +[1.0.2]: https://github.com/eric-wien/ogma/releases/tag/v1.0.2 [1.0.1]: https://github.com/eric-wien/ogma/releases/tag/v1.0.1 [1.0.0]: https://github.com/eric-wien/ogma/releases/tag/v1.0.0 [0.5.0]: https://github.com/eric-wien/ogma/releases/tag/v0.5.0 diff --git a/README.md b/README.md index 03d0b56..391302d 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,12 @@ subcommands — granting it does *not* grant arbitrary shell): `status`, `logs [ `health`, `ticket `, `tickets`. To let the bot use it, add the scoped rule to `OGMA_ALLOWED_TOOLS` (see `.env.example`). +**Host-specific commands.** To add commands for your own box without forking the tool, drop an +executable `bin/ogmactl.local` (gitignored) — `ogmactl` delegates any subcommand it doesn't +recognise to it. Keep the same discipline as `ogmactl`: whitelist your commands and refuse the +rest (the bot can reach them through `ogmactl`, so keep them read-only and safe). On a stock +install there's no such file and unknown commands are refused as before. + ## Scheduled routines (optional) - **`bin/briefing`** — deterministic news (RSS via `bin/news-fetch`) + weather, summarised by Claude, delivered via `bin/tg-send`. Configure feeds/location/owner in `.env`. Dry-run: diff --git a/bin/ogmactl b/bin/ogmactl index 6f3c693..080d217 100755 --- a/bin/ogmactl +++ b/bin/ogmactl @@ -12,9 +12,13 @@ SVC="ogma-gateway" LOG="$BASE/gateway.log" ENV="$BASE/.env" TICKETS="$BASE/tickets" +# Optional, operator-provided, gitignored extension for host-specific commands +# (e.g. a Pi-hole diagnostic). Keeps the public tool host-agnostic. See the *) case. +LOCAL="$BASE/bin/ogmactl.local" usage() { echo "ogmactl: allowed commands — status | logs [N] | restart | health | ticket | tickets" + [ -x "$LOCAL" ] && "$LOCAL" help 2>/dev/null } # Read a config value (OGMA_) from .env. @@ -90,6 +94,13 @@ case "$cmd" in usage ;; *) + # Delegate to the optional host-local extension if the operator installed one. + # It MUST whitelist its own subcommands and refuse the rest (same discipline as + # this script), since the bot can reach it through ogmactl. On a stock install + # there is no such file and unknown commands are refused, as before. + if [ -x "$LOCAL" ]; then + exec "$LOCAL" "$@" + fi echo "ogmactl: refused unknown command '$cmd'"; usage; exit 2 ;; esac