POST, GET and DELETE under /api/v1/chats/{id}/webhooks, for the chats
that GET /api/v1/chats lists. The webhooks are kept in
$DATA_DIR/webhooks.json, mode 0600, which each change replaces whole
through a temporary file in the same directory and a rename. bot.Run
reads the file before it starts the chat client: absent means none, and
a file that cannot be read aborts startup. Reading a JSON request body
moved into decodeBody, which the messages endpoint now shares. Nothing
is posted to a webhook yet.
Model: opus-5-5
`GET /api/v1/chats/{id}/messages?count=N` returns a chat's recent messages, oldest first (`count` 1 to 100, default 20), and `POST` to the same path sends a text message and returns it once the chat client has taken it. Both answer `404` for any id the chats list does not show, looked up in the same contact list. The message record is defined once, for the webhooks to reuse.
Disclosures: items are read five at a time, because one item can be many times its text and 100 at once could pass the 16 MiB read limit; text too long gets `413`, a contact who deleted the chat `409` (unverified for one still connecting); a query the server cannot read gets its own `400`.
Model: opus-5-5
The repository moved to `sneak/simplexcalc`; the Getting Started clone command still named `clawbot/simplexcalc`, which only redirects. It was the only mention of the old location.
Model: opus-5-5
The bot now serves an HTTP API on `PORT` (default 8080) beside the chat client, whose WebSocket stays on 127.0.0.1 inside the container. Every request needs `Authorization: Bearer` with the credential from the file named by `API_TOKEN_FILE`, compared in constant time; with no credential configured every request is refused, `OPTIONS *` included. `GET /api/v1/chats` lists the bot's chats. Responses carry the security headers from the repository policies; bodies, requests and the server are time- and size-bounded. The chat client stops only after the API has finished its requests.
Disclosures: `contact_deleted` is an extra field; 404 and 405 answer in JSON; requests net/http cannot parse are refused by net/http without the security headers; three gosec findings are suppressed as false positives.
Model: opus-5-5
The calculator now takes `^` (or `**`) for powers and `%` for modulo. Powers bind tighter than a sign on their left and group to the right, so `-2^2` is `-4` and `2^3^2` is `512`; `%` sits with `*` and `/` and takes the sign of the divisor. A small parser of our own replaces `go/parser`, which cannot express `^`; `go/constant` still computes.
A whole-number exponent is exact; a fractional one is computed in float64. Every number is held as a fraction under 4096 bits, and a float64 result must be a normal double, so one message cannot stall the bot; anything else gets "That needs a number too large or too small for me."
Disclosure: tiny values below about 2.2e-308, which `next` answered, are now refused.
Model: opus-5-5
`cmd/simplexcalc/` now holds only `main.go`, whose body is one call, `os.Exit(cli.Main(version))`, as the Go style guide requires. The command tree and the `run` and `version` commands moved unchanged into `internal/cli`, with tests for `version` and for an unknown command. Output streams, exit statuses and the `-X main.version` build flag are as before.
Disclosure: the comment in `execute` saying cobra has already printed the error is false, since the root command silences cobra's errors; it moved unchanged and is left for a follow-up.
Model: opus-5-5