From bcf062ece051366270f51636976012df2c06dca5 Mon Sep 17 00:00:00 2001 From: Waldo <099waldo@gmail.com> Date: Sat, 7 Mar 2026 07:25:36 -0700 Subject: [PATCH] Added .env to gitignore, added CLAUDE.md --- .gitignore | 1 + CLAUDE.md | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 CLAUDE.md diff --git a/.gitignore b/.gitignore index 1d1396c..2fa102e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /bin /result sox +.env diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..6d76cd7 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,27 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## What this is + +Sox is a Campfire bot written in Go. It runs as an HTTP server (default port `4567`, overridable via `PORT` env var) that receives webhook POST requests from Campfire and responds with HTML-formatted text. + +## Commands + +```bash +make build # builds binary to bin/sox +make test # runs all tests with verbose output +go test -run TestSplitFirstWord ./... # run a single test +``` + +The `math` command requires `qalc` (libqalculate) on PATH. Tests that need it skip automatically if it's absent. + +## Architecture + +**Plugin system** (`plugin.go`): Each command is a struct implementing the `Plugin` interface (`Name()`, `ShortHelp()`, `DetailedHelp()`, `Execute()`). Plugins self-register via `registerPlugin()` called from `init()` in `main.go`. The global `registry` map (`map[string]Plugin`) routes commands by name. + +**Request handling** (`main.go`): `commandHandler` decodes the Campfire JSON webhook into `BotMessage`, then `executeCommand` splits the plain-text body into command + arguments. If the command isn't recognized, it falls back to the user's last successfully used command (stored in `userLastCommandType`, a `map[string]string` keyed by username). The `help` command is excluded from last-command memory. + +**Adding a new command**: Create a `cmd_.go` file, implement the `Plugin` interface, and add `registerPlugin(YourPlugin{})` to `init()` in `main.go`. + +**HTTP tracing** (`request_trace.go`, `cmd_trace.go`): `TraceRequest` uses `net/http/httptrace` to instrument a GET request with a 3-second timeout and returns a `RequestTrace` struct with timestamps for each phase (DNS, connect, TLS, headers, first byte, last byte).