From 6400135680445dc3c1e4344635033fe2051704e3 Mon Sep 17 00:00:00 2001 From: Anthony Baldwin <6219998+anthonybaldwin@users.noreply.github.com> Date: Fri, 8 May 2026 19:29:30 -0700 Subject: [PATCH 1/2] =?UTF-8?q?rename:=20statuspage-discord=20=E2=86=92=20?= =?UTF-8?q?squawk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bot already covers both Statuspage.io and incident.io and is built to add more provider adapters; the original "statuspage-discord" name implied vendor coupling that no longer fits. Squawk reads as source-agnostic and matches the bot's actual job (broadcasting incident "squawks" to Discord). Surface touched: - package.json `name` → squawk - compose.yml volume name → squawk_data - README + AGENTS.md branding (vendor mentions of Statuspage.io stay) - docs/wiki/* — repo URL paths, volume names, repo-name examples - .github/workflows/sync-wiki.yml — repo paths Env var rename (with backwards-compat alias): - STATUSPAGE_MONITORS_JSON → MONITORS_JSON (the multi-monitor list covers both Statuspage and incident.io; the old name was misleading). Legacy name is still honored with a startup deprecation warning. - STATUSPAGE_BASE_URL stays as-is — it specifically names the Statuspage.io single-monitor URL, which is accurate. Provider adapter filenames (src/providers/statuspage.ts) and the "Statuspage.io" / "incident.io" vendor name references throughout the codebase are intentionally unchanged — those refer to upstream products not the bot's brand. Repo move on GitHub still pending; this commit is the in-tree rename. Co-Authored-By: Claude Opus 4.7 (1M context) --- .env.example | 6 ++++-- .github/workflows/sync-wiki.yml | 2 +- AGENTS.md | 6 ++++-- README.md | 28 ++++++++++++++++------------ compose.yml | 4 ++-- docs/wiki/API-Integration.md | 2 +- docs/wiki/Architecture.md | 2 +- docs/wiki/Configuration.md | 4 ++-- docs/wiki/Contributing.md | 6 +++--- docs/wiki/Deployment.md | 8 ++++---- docs/wiki/Development.md | 4 ++-- docs/wiki/Home.md | 2 +- docs/wiki/State-Management.md | 2 +- package.json | 2 +- src/index.ts | 20 ++++++++++++++++---- 15 files changed, 59 insertions(+), 39 deletions(-) diff --git a/.env.example b/.env.example index e7b6074..ad57a8a 100644 --- a/.env.example +++ b/.env.example @@ -6,8 +6,10 @@ DISCORD_CHANNEL_ID= STATUSPAGE_BASE_URL=https://status.atlassian.com # Multi-monitor config overrides the two fields above when set. Accepts Statuspage.io and # incident.io URLs. Optional per-entry "provider" field: "statuspage" (default) or "incidentio". -# STATUSPAGE_MONITORS_JSON=[{"id":"atlassian","channelId":"123456789012345678","baseUrl":"https://status.atlassian.com","label":"Atlassian"},{"id":"openai","channelId":"234567890123456789","baseUrl":"https://status.openai.com","label":"OpenAI","provider":"incidentio"}] -STATUSPAGE_MONITORS_JSON= +# MONITORS_JSON=[{"id":"atlassian","channelId":"123456789012345678","baseUrl":"https://status.atlassian.com","label":"Atlassian"},{"id":"openai","channelId":"234567890123456789","baseUrl":"https://status.openai.com","label":"OpenAI","provider":"incidentio"}] +# Legacy alias `STATUSPAGE_MONITORS_JSON` is still honored for backwards +# compatibility but emits a deprecation warning at startup; prefer MONITORS_JSON. +MONITORS_JSON= POLL_INTERVAL_MS=180000 POST_EXISTING_UPDATES_ON_START=false ENABLE_STATUS_COMMAND=true diff --git a/.github/workflows/sync-wiki.yml b/.github/workflows/sync-wiki.yml index aa05749..d854aed 100644 --- a/.github/workflows/sync-wiki.yml +++ b/.github/workflows/sync-wiki.yml @@ -18,7 +18,7 @@ jobs: - name: Clone wiki repo run: | - git clone "https://x-access-token:${{ secrets.WIKI_SYNC_PAT }}@github.com/anthonybaldwin/statuspage-discord.wiki.git" wiki + git clone "https://x-access-token:${{ secrets.WIKI_SYNC_PAT }}@github.com/anthonybaldwin/squawk.wiki.git" wiki - name: Sync docs into wiki run: | diff --git a/AGENTS.md b/AGENTS.md index 4fa7751..2a79d67 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,7 +4,9 @@ Instructions for AI coding agents working on this project. **All agents MUST rea ## Project Overview -statuspage-discord is a Bun-based Discord bot that polls public status pages (Statuspage.io and incident.io are supported) and posts incident updates as threaded conversations in Discord. It supports multiple monitors, runtime monitor management, and persistent state. +Squawk is a Bun-based Discord bot that polls public status pages (Statuspage.io and incident.io are supported) and posts incident updates as threaded conversations in Discord. It supports multiple monitors, runtime monitor management, and persistent state. + +The repo was previously named `statuspage-discord`. The legacy `STATUSPAGE_MONITORS_JSON` env var is still honored as a deprecated alias for `MONITORS_JSON`. ## Tech Stack @@ -122,7 +124,7 @@ Every command handler follows: See `.env.example` for the full list. Key ones: - `DISCORD_TOKEN`, `DISCORD_APPLICATION_ID` (required) -- `STATUSPAGE_MONITORS_JSON` or `DISCORD_CHANNEL_ID` + `STATUSPAGE_BASE_URL` +- `MONITORS_JSON` or `DISCORD_CHANNEL_ID` + `STATUSPAGE_BASE_URL` (legacy `STATUSPAGE_MONITORS_JSON` still honored with deprecation warning) - `POLL_INTERVAL_MS` (default 60000) - `ENABLE_*_COMMAND` feature flags (all default true, includes `ENABLE_CLEANUP_COMMAND`) - `APP_VERSION` (optional, auto-set in Docker builds via build arg, falls back to `package.json` version) diff --git a/README.md b/README.md index b153031..3080783 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# statuspage-discord +# Squawk A Bun-based Discord bot that: @@ -26,23 +26,23 @@ bun dev # Watch mode (or `bun start` for production) docker compose up -d # Production deployment with Docker Compose ``` -A prebuilt image is available at `ghcr.io/anthonybaldwin/statuspage-discord:main`. +A prebuilt image is available at `ghcr.io/anthonybaldwin/squawk:latest`. ## Documentation -Full docs live in the [wiki](https://github.com/anthonybaldwin/statuspage-discord/wiki): +Full docs live in the [wiki](https://github.com/anthonybaldwin/squawk/wiki): | Page | Description | |------|-------------| -| [Architecture](https://github.com/anthonybaldwin/statuspage-discord/wiki/Architecture) | System design, data flow, and module structure | -| [Configuration](https://github.com/anthonybaldwin/statuspage-discord/wiki/Configuration) | Environment variables, multi-monitor setup, feature flags | -| [Commands](https://github.com/anthonybaldwin/statuspage-discord/wiki/Commands) | All slash commands with usage and permissions | -| [Incident Lifecycle](https://github.com/anthonybaldwin/statuspage-discord/wiki/Incident-Lifecycle) | How incidents are tracked from creation to resolution or removal | -| [State Management](https://github.com/anthonybaldwin/statuspage-discord/wiki/State-Management) | Persistence format, migration, and locking | -| [API Integration](https://github.com/anthonybaldwin/statuspage-discord/wiki/API-Integration) | Supported providers, endpoints, and how to add a new provider | -| [Deployment](https://github.com/anthonybaldwin/statuspage-discord/wiki/Deployment) | Docker, Docker Compose, CI/CD, and production notes | -| [Development](https://github.com/anthonybaldwin/statuspage-discord/wiki/Development) | Local setup, tooling, and contribution guide | -| [Contributing](https://github.com/anthonybaldwin/statuspage-discord/wiki/Contributing) | How to contribute, code conventions, and documentation rules | +| [Architecture](https://github.com/anthonybaldwin/squawk/wiki/Architecture) | System design, data flow, and module structure | +| [Configuration](https://github.com/anthonybaldwin/squawk/wiki/Configuration) | Environment variables, multi-monitor setup, feature flags | +| [Commands](https://github.com/anthonybaldwin/squawk/wiki/Commands) | All slash commands with usage and permissions | +| [Incident Lifecycle](https://github.com/anthonybaldwin/squawk/wiki/Incident-Lifecycle) | How incidents are tracked from creation to resolution or removal | +| [State Management](https://github.com/anthonybaldwin/squawk/wiki/State-Management) | Persistence format, migration, and locking | +| [API Integration](https://github.com/anthonybaldwin/squawk/wiki/API-Integration) | Supported providers, endpoints, and how to add a new provider | +| [Deployment](https://github.com/anthonybaldwin/squawk/wiki/Deployment) | Docker, Docker Compose, CI/CD, and production notes | +| [Development](https://github.com/anthonybaldwin/squawk/wiki/Development) | Local setup, tooling, and contribution guide | +| [Contributing](https://github.com/anthonybaldwin/squawk/wiki/Contributing) | How to contribute, code conventions, and documentation rules | ## Notes @@ -50,3 +50,7 @@ Full docs live in the [wiki](https://github.com/anthonybaldwin/statuspage-discor - For development, setting `DISCORD_GUILD_ID` makes slash-command registration update faster than global commands. - On first startup, the bot seeds current incident-update IDs without posting them unless `POST_EXISTING_UPDATES_ON_START=true`. - The bot needs Send Messages, Embed Links, Create Public Threads, and Manage Messages permissions. + +## Previously known as + +This project was originally named `statuspage-discord`. The new name reflects that it covers more than just Statuspage.io. The legacy `STATUSPAGE_MONITORS_JSON` env var is still honored (with a deprecation warning) — prefer `MONITORS_JSON` going forward. diff --git a/compose.yml b/compose.yml index c9b8b2f..f7fc595 100644 --- a/compose.yml +++ b/compose.yml @@ -3,8 +3,8 @@ services: build: . env_file: .env volumes: - - statuspage_data:/app/data + - squawk_data:/app/data restart: unless-stopped volumes: - statuspage_data: + squawk_data: diff --git a/docs/wiki/API-Integration.md b/docs/wiki/API-Integration.md index 88e2c22..4c18a32 100644 --- a/docs/wiki/API-Integration.md +++ b/docs/wiki/API-Integration.md @@ -20,7 +20,7 @@ Current probe order: 1. **incident.io** — probed first because many incident.io pages also expose a Statuspage-compatible `/api/v2/` shim, but the shim returns empty update bodies and a truncated history. Probing incident.io first ensures we use the richer native widget API when available. 2. **Statuspage.io** — fallback for pages that are not on incident.io. -Monitors loaded from `data/monitors.json` or `STATUSPAGE_MONITORS_JSON` that pre-date multi-provider support default to `statuspage` for backwards compatibility. +Monitors loaded from `data/monitors.json` or `MONITORS_JSON` that pre-date multi-provider support default to `statuspage` for backwards compatibility. ## Statuspage.io Adapter diff --git a/docs/wiki/Architecture.md b/docs/wiki/Architecture.md index 64813be..44e48db 100644 --- a/docs/wiki/Architecture.md +++ b/docs/wiki/Architecture.md @@ -2,7 +2,7 @@ ## Overview -statuspage-discord is a Bun/TypeScript application with bot logic in `src/index.ts` (~1700 lines, single file by design) and provider-specific API adapters in `src/providers/` (one small file per provider). It connects to Discord via [discord.js](https://discord.js.org/) and polls supported public status page APIs on a timer. +squawk is a Bun/TypeScript application with bot logic in `src/index.ts` (~1700 lines, single file by design) and provider-specific API adapters in `src/providers/` (one small file per provider). It connects to Discord via [discord.js](https://discord.js.org/) and polls supported public status page APIs on a timer. ## Data Flow diff --git a/docs/wiki/Configuration.md b/docs/wiki/Configuration.md index 2c35db3..e290a81 100644 --- a/docs/wiki/Configuration.md +++ b/docs/wiki/Configuration.md @@ -16,7 +16,7 @@ You must configure monitors using **one** of these two approaches: ### Option A: Multi-Monitor (Recommended) ```env -STATUSPAGE_MONITORS_JSON=[{"id":"atlassian","channelId":"123456789","baseUrl":"https://status.atlassian.com","label":"Atlassian"},{"id":"openai","channelId":"987654321","baseUrl":"https://status.openai.com","label":"OpenAI","provider":"incidentio"}] +MONITORS_JSON=[{"id":"atlassian","channelId":"123456789","baseUrl":"https://status.atlassian.com","label":"Atlassian"},{"id":"openai","channelId":"987654321","baseUrl":"https://status.openai.com","label":"OpenAI","provider":"incidentio"}] ``` Each monitor object requires: @@ -37,7 +37,7 @@ DISCORD_CHANNEL_ID=123456789 STATUSPAGE_BASE_URL=https://status.atlassian.com ``` -This creates a single monitor with ID `default`. If `STATUSPAGE_MONITORS_JSON` is set, these two variables are ignored. +This creates a single monitor with ID `default`. If `MONITORS_JSON` is set, these two variables are ignored. ### Runtime Monitors diff --git a/docs/wiki/Contributing.md b/docs/wiki/Contributing.md index ab90e18..d035896 100644 --- a/docs/wiki/Contributing.md +++ b/docs/wiki/Contributing.md @@ -1,12 +1,12 @@ # Contributing -Thanks for your interest in contributing to statuspage-discord! +Thanks for your interest in contributing to squawk! ## Getting Started 1. **Open an issue** to discuss the change before starting work on anything non-trivial 2. **Fork the repo** and create a feature branch off `main` -3. **Set up your environment** — see the [Development](https://github.com/anthonybaldwin/statuspage-discord/wiki/Development) page for local setup +3. **Set up your environment** — see the [Development](https://github.com/anthonybaldwin/squawk/wiki/Development) page for local setup 4. **Make your changes**, ensuring they follow the conventions below 5. **Open a pull request** against `main` @@ -101,4 +101,4 @@ gh pr merge --rebase --delete-branch ## Questions? -Open a [GitHub issue](https://github.com/anthonybaldwin/statuspage-discord/issues) or start a [discussion](https://github.com/anthonybaldwin/statuspage-discord/discussions). +Open a [GitHub issue](https://github.com/anthonybaldwin/squawk/issues) or start a [discussion](https://github.com/anthonybaldwin/squawk/discussions). diff --git a/docs/wiki/Deployment.md b/docs/wiki/Deployment.md index 470fbc2..97070b7 100644 --- a/docs/wiki/Deployment.md +++ b/docs/wiki/Deployment.md @@ -10,7 +10,7 @@ docker compose up -d The `compose.yml` configures: - `env_file: .env` for secret injection (never baked into the image) -- `statuspage_data` named volume mounted at `/app/data` for persistent state +- `squawk_data` named volume mounted at `/app/data` for persistent state - `restart: unless-stopped` for automatic recovery State survives container restarts, recreations, and image updates (e.g., via [Watchtower](https://containrrr.dev/watchtower/) or [WUD](https://github.com/fmartinou/whats-up-docker)). @@ -20,13 +20,13 @@ State survives container restarts, recreations, and image updates (e.g., via [Wa Build: ```bash -docker build -t statuspage-discord . +docker build -t squawk . ``` Run: ```bash -docker run --rm --env-file .env -v statuspage_data:/app/data statuspage-discord +docker run --rm --env-file .env -v squawk_data:/app/data squawk ``` ## Prebuilt Image @@ -34,7 +34,7 @@ docker run --rm --env-file .env -v statuspage_data:/app/data statuspage-discord A multi-arch image (ARM64 + AMD64) is published to GitHub Container Registry on every push to `main`: ```bash -docker pull ghcr.io/anthonybaldwin/statuspage-discord:latest +docker pull ghcr.io/anthonybaldwin/squawk:latest ``` Tags: diff --git a/docs/wiki/Development.md b/docs/wiki/Development.md index 551cf2e..f67dcad 100644 --- a/docs/wiki/Development.md +++ b/docs/wiki/Development.md @@ -9,8 +9,8 @@ ## Setup ```bash -git clone https://github.com/anthonybaldwin/statuspage-discord.git -cd statuspage-discord +git clone https://github.com/anthonybaldwin/squawk.git +cd squawk bun install cp .env.example .env # Edit .env with your bot token and channel IDs diff --git a/docs/wiki/Home.md b/docs/wiki/Home.md index 1e45040..30af996 100644 --- a/docs/wiki/Home.md +++ b/docs/wiki/Home.md @@ -1,4 +1,4 @@ -# statuspage-discord +# squawk A Bun-based Discord bot that monitors public status pages — [Statuspage.io](https://www.atlassian.com/software/statuspage) and [incident.io](https://incident.io/) are supported — and posts incident updates to Discord as threaded conversations. diff --git a/docs/wiki/State-Management.md b/docs/wiki/State-Management.md index 240dd51..702ede4 100644 --- a/docs/wiki/State-Management.md +++ b/docs/wiki/State-Management.md @@ -1,6 +1,6 @@ # State Management -The bot persists its state to JSON files in the `data/` directory. In Docker deployments, this directory is backed by a named volume (`statuspage_data`). +The bot persists its state to JSON files in the `data/` directory. In Docker deployments, this directory is backed by a named volume (`squawk_data`). ## Files diff --git a/package.json b/package.json index 59f8b6c..114ebc2 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "statuspage-discord", + "name": "squawk", "version": "0.1.0", "private": true, "type": "module", diff --git a/src/index.ts b/src/index.ts index abcdb4a..e7f8577 100644 --- a/src/index.ts +++ b/src/index.ts @@ -59,6 +59,11 @@ const envSchema = z.object({ DISCORD_GUILD_ID: z.string().min(1).optional(), DISCORD_CHANNEL_ID: z.string().min(1).optional(), STATUSPAGE_BASE_URL: z.string().url().optional(), + // MONITORS_JSON is the canonical multi-monitor config (covers both + // Statuspage.io and incident.io). STATUSPAGE_MONITORS_JSON is the + // pre-rename alias — still honored, with a deprecation warning at + // startup. Either may be set; if both are set, MONITORS_JSON wins. + MONITORS_JSON: z.string().optional(), STATUSPAGE_MONITORS_JSON: z.string().optional(), POLL_INTERVAL_MS: z.coerce.number().int().positive().default(60_000), POST_EXISTING_UPDATES_ON_START: booleanFromEnv.default("false"), @@ -83,8 +88,15 @@ type RuntimeMonitorFile = { }; function loadMonitors(env: z.infer): MonitorConfig[] { - if (env.STATUSPAGE_MONITORS_JSON) { - const parsed = JSON.parse(env.STATUSPAGE_MONITORS_JSON) as unknown; + const rawMonitors = env.MONITORS_JSON ?? env.STATUSPAGE_MONITORS_JSON; + if (rawMonitors) { + if (!env.MONITORS_JSON && env.STATUSPAGE_MONITORS_JSON) { + console.warn( + "STATUSPAGE_MONITORS_JSON is deprecated; rename to MONITORS_JSON. " + + "The legacy name still works but will be removed in a future release.", + ); + } + const parsed = JSON.parse(rawMonitors) as unknown; return z.array(monitorSchema).parse(parsed); } @@ -99,7 +111,7 @@ function loadMonitors(env: z.infer): MonitorConfig[] { } throw new Error( - "Configure either STATUSPAGE_MONITORS_JSON or both DISCORD_CHANNEL_ID and STATUSPAGE_BASE_URL.", + "Configure either MONITORS_JSON or both DISCORD_CHANNEL_ID and STATUSPAGE_BASE_URL.", ); } @@ -1821,7 +1833,7 @@ async function handleMonitorList(interaction: ChatInputCommandInteraction) { if (monitors.length === 0) { await interaction.editReply({ - content: "No monitors configured. Use `/monitor add` or set `STATUSPAGE_MONITORS_JSON`.", + content: "No monitors configured. Use `/monitor add` or set `MONITORS_JSON`.", }); return; } From 066b35e5d3c1d8e896186bc9768033dadbed5338 Mon Sep 17 00:00:00 2001 From: Anthony Baldwin <6219998+anthonybaldwin@users.noreply.github.com> Date: Fri, 8 May 2026 19:30:19 -0700 Subject: [PATCH 2/2] =?UTF-8?q?revert=20workflow=20URL=20update=20?= =?UTF-8?q?=E2=80=94=20restore=20for=20follow-up=20with=20workflow-scoped?= =?UTF-8?q?=20token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/sync-wiki.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync-wiki.yml b/.github/workflows/sync-wiki.yml index d854aed..aa05749 100644 --- a/.github/workflows/sync-wiki.yml +++ b/.github/workflows/sync-wiki.yml @@ -18,7 +18,7 @@ jobs: - name: Clone wiki repo run: | - git clone "https://x-access-token:${{ secrets.WIKI_SYNC_PAT }}@github.com/anthonybaldwin/squawk.wiki.git" wiki + git clone "https://x-access-token:${{ secrets.WIKI_SYNC_PAT }}@github.com/anthonybaldwin/statuspage-discord.wiki.git" wiki - name: Sync docs into wiki run: |