Instructions for coding agents working in this repository.
This is a flat Go package at the module root: package nerimity, module path
github.com/JoddabodScripts/neri-go. There is no internal/ or pkg/ split; the
surface area doesn't justify one. Files are organized by concept, not by
layer:
client.go:Client,Options, connection lifecycle (Login,Close), reconnect/backoff, the dispatch goroutine, cache storesevents.go:On*handler registration and the WebSocket event to cache update to handler dispatch logicsocketio.go: the minimal Engine.IO v4 / Socket.IO v5 client overgorilla/websocket. This is the only file that speaks the wire protocol at the frame levelrawdata.go: unexported structs (raw*) that mirror the JSON the server actually sends, used only for unmarshallingrest.go: REST calls (send/edit/delete message, ban/kick, button callback)message.go,channel.go,user.go,member.go,server.go,role.go,reaction.go,button.go: the exported domain typesmentions.go,permissions.go,html.go: pure parsing/helper logic with no network dependencyattachment.go,webhook.go,commands.go: attachment upload, webhook sending, slash-command registrationcache.go: the generic LRU cache backing every collection (Client.Servers,Server.Members, the message cache, etc.)examples/: runnable example bots, also serves as compiled documentationdocs/: prose documentation
go build ./...
go vet ./...
gofmt -l . # should print nothing; gofmt -w . to fix
go test ./...All four must pass before a change is done. gofmt -l . printing any path is
a failure, not a suggestion.
Nerimity has no public API spec. The only source of truth for event names,
REST endpoints, and payload shapes is the reference JavaScript SDK at
~/nrepos/nerimity.js (src/classes/Client.ts, src/EventNames.ts,
src/RawData.ts, src/services/). If that path doesn't exist in your
environment, ask for it before guessing; do not invent field names or
endpoints from training data. When adding a new event or endpoint:
- Find the equivalent in nerimity.js first: the exact socket event string
(
src/EventNames.ts), the payload shape (src/RawData.ts), and how the JSClientmutates its caches in response (src/classes/Client.ts'sEventHandlersclass). - Mirror the cache mutation logic, not just the event name. The JS SDK's
onXxxhandlers inEventHandlersshow exactly what gets added, removed, or patched in which collection; get this wrong and consumers see stale or missing data even though the event fired. - Add the raw struct to
rawdata.go, the public type/field to the relevant domain file, the socket event constant and handler toevents.go.
- Errors: return
(T, error), never panic on request failures. Usefmt.Errorf("nerimity: doing the thing: %w", err). Always prefix withnerimity:so errors are identifiable when this package is one dependency among many in a larger bot. - Context: every method that makes a network call takes
context.Contextas its first argument. - Naming: exported types/methods use Go naming (
ServerID, notserverId); unexportedraw*structs keep the wire's camelCase viajson:tags, not in the Go field names. - Caches: never expose the internal
cache[T]type directly. Public accessors return[]Tsnapshots (seeServer.Members(),Client.Servers()) so callers can't corrupt cache internals or deadlock by holding a lock across a callback. - New events: add the
On<EventName>registration method inevents.gonext to the others, add the socket event name constant, add acaseinClient.handleEvent, and updatedocs/events.md. - Tests: anything with parsing/pure logic (mention parsing, command
parsing, HTML escaping, permission bit helpers, the LRU cache, Socket.IO
frame parsing) must have unit tests; they don't need a live server. Files
needing a live Nerimity connection are integration-only and are not part of
go test ./...; there are none currently, and none should be added without a way to skip them in CI.