feat: add comprehensive AI coding instructions for Thoughtful Discord Bot

This commit is contained in:
Space-Banane
2026-01-23 13:39:46 +01:00
parent c20855ae6e
commit 151c250e62

102
.github/copilot-instructions.md vendored Normal file
View File

@@ -0,0 +1,102 @@
# Thoughtful Discord Bot - AI Coding Instructions
## Project Overview
A Go Discord bot that integrates with the Thoughtful API for managing ideas through Discord commands. Built with `discordgo` library, uses JSON for user config persistence.
## Architecture
### Component Structure
- **bot.go**: Main entry point. Handles Discord session, registers handlers, manages bot lifecycle
- **commands/**: Modular command system where each command is a separate file
- `commands.go`: Command registry and interaction router
- `storage.go`: JSON-based user config persistence (users.json)
- Individual command files: `setup.go`, `list.go`, `delete.go`, `logout.go`
### Key Design Patterns
**Command Registration Pattern**: Each command implements the `Cmd` struct:
```go
type Cmd struct {
Command *discordgo.ApplicationCommand
Handler func(s *discordgo.Session, ic *discordgo.InteractionCreate)
AutocompleteHandler func(s *discordgo.Session, ic *discordgo.InteractionCreate) // optional
}
```
All commands are registered via `getAllCommands()` in [commands/commands.go](../commands/commands.go).
**Dual Command Interface**: The bot supports both:
- Slash commands (e.g., `/setup`, `/list`) via Discord's ApplicationCommand API
- Legacy text commands (e.g., `.thought Title; Description`) for backward compatibility
**User State Management**: Per-user configs (Thoughtful instance URL + API key) stored in `users.json`. Thread-safe access via mutex in [commands/storage.go](../commands/storage.go).
**Modal-Based Setup**: `/setup` uses Discord modals (not option prompts) to collect sensitive credentials privately.
### External Dependencies
- **Thoughtful API**: External idea management service. Requires:
- Base URL (user-provided, e.g., `https://instance.com`)
- API key authentication via `API-Authentication` header
- Endpoints: `/api/ideas/create`, `/api/ideas/list`, `/api/ideas/delete`
- **Discord API**: via `github.com/bwmarrin/discordgo` library
## Developer Workflows
### Running Locally
```sh
# Set environment variable
$env:DISCORD_BOT_TOKEN="your_token_here"
# Run directly
go run .
```
### Docker Deployment
The bot is designed for Docker Compose deployment. See [docker-compose.yml](../docker-compose.yml):
- Uses `golang:1.25` image (note: uncommon version - likely should be `1.21` or `1.22`)
- Auto-pulls git changes on container start
- Requires `.env` file with `DISCORD_BOT_TOKEN`
### Adding New Commands
1. Create new file in `commands/` (e.g., `mycommand.go`)
2. Implement `newMyCommand()` returning `*Cmd`
3. Add to `getAllCommands()` in [commands/commands.go](../commands/commands.go)
4. Command automatically registers on bot startup
## Project-Specific Conventions
### Error Handling
- Use `respondError()` helper for interaction failures (defined in command files)
- Silent failures acceptable for autocomplete handlers
- Channel messages for `.thought` command errors
### User Identification
Discord interactions may have `User` OR `Member.User` depending on context:
```go
user := ic.User
if user == nil {
user = ic.Member.User
}
```
Always check both when accessing user data.
### API Communication
- Always trim trailing slashes from instance URLs: `url = strings.TrimSuffix(url, "/")`
- Use `API-Authentication` header (not `Authorization`)
- 401 status codes mean invalid/expired API keys
### Storage Layer
- **Never** edit `users.json` directly - always use `storage.go` functions
- Operations are mutex-protected but not transactional
- Corrupted JSON automatically resets to empty map
## Critical Gotchas
1. **Intents Required**: Bot needs `IntentsGuildMessages` (set in [bot.go](../bot.go#L40)). Message Content Intent must be enabled in Discord Developer Portal.
2. **Slash Command Updates**: Slash commands persist in Discord. To update, uncomment command cleanup code in [commands/commands.go](../commands/commands.go#L30-L33).
3. **Modal Response Type**: Setup uses `InteractionResponseModal`, not `InteractionResponseChannelMessageWithSource`.
4. **Autocomplete Filtering**: Delete command autocomplete should filter by user input but currently returns all ideas - see [commands/delete.go](../commands/delete.go#L86-L100).
5. **No Database**: All state in `users.json`. Loss of this file = all users must re-run `/setup`.