-
Notifications
You must be signed in to change notification settings - Fork 0
Development
github-actions[bot] edited this page May 9, 2026
·
2 revisions
- Bun (v1.3.10+ recommended)
- A Discord bot token and application ID (Discord Developer Portal)
- A test Discord server with a text channel
git clone https://github.com/anthonybaldwin/squawk.git
cd squawk
bun install
cp .env.example .env
# Edit .env with your bot token and channel IDsbun dev # Watch mode — auto-restarts on file changes
bun start # Single runSet DISCORD_GUILD_ID in your .env to your test server's ID. This makes slash commands register instantly (guild-scoped) instead of waiting up to an hour for global propagation.
src/index.ts # All bot logic (single file)
data/state.json # Runtime state (auto-created)
data/monitors.json # Runtime monitors (auto-created)
.env # Local secrets (git-ignored)
.env.example # Configuration template
The source is a single TypeScript file organized into logical sections. See Architecture for a detailed breakdown.
Key conventions:
- Functions are ordered by dependency (callees above callers)
- All Discord embed construction is in the
render*functions - State mutations happen in
postLatestUpdatesForMonitorand command handlers - Error handling uses specific DiscordAPIError codes rather than catch-all patterns
bun run tsc --noEmit # Type-check without emittingThe tsconfig.json uses strict mode with ES2022 target and Bun module resolution.
- Set
POST_EXISTING_UPDATES_ON_START=trueto see updates immediately - Use
/testpostto preview status embeds without affecting state - Use
/replayto re-post incident timelines after cleanup - Use
/cleanto wipe bot messages when iterating - Monitor a Statuspage with frequent incidents (e.g.,
https://status.atlassian.com) for realistic testing
docker compose build # Rebuild image
docker compose up # Run with logs visible
docker compose down # Stop and remove container (volume preserved)- Add a feature flag to
envSchema(e.g.,ENABLE_MY_COMMAND) - Add the
SlashCommandBuilderinbuildCommands(), gated by the flag - Write a
handleMyCommand()function following the existing patterns:- Defer reply with ephemeral flag
- Resolve monitor target
- Assert channel access
- Perform action
- Edit reply with result
- Add the command dispatch in the
interactionCreatehandler - Update
.env.example,README.md,docs/wiki/Commands.md, andCLAUDE.md