diff --git a/src/components/navigation.ts b/src/components/navigation.ts index 250b11f..873cc6e 100644 --- a/src/components/navigation.ts +++ b/src/components/navigation.ts @@ -292,6 +292,11 @@ export const navigation = [ label: "Veluna", link: "/projects/veluna", badge: { text: "v1.0.0", variant: "tip" }, + }, + { + label: "Callista", + link: "/projects/callista", + badge: { text: "v1.0.0", variant: "tip" }, } ].sort((a, b) => a.label.localeCompare(b.label)), }, diff --git a/src/content/docs/projects/callista.md b/src/content/docs/projects/callista.md new file mode 100644 index 0000000..3c3a9d9 --- /dev/null +++ b/src/content/docs/projects/callista.md @@ -0,0 +1,373 @@ +--- +title: Callista +--- + +Callista (hereinafter the "Application") is a Discord bot that allows users to bookmark messages so they can find them later. The Application provides a simple interface for saving message links via DM, with optional note-taking capabilities to help organize and remember why messages were bookmarked. + +## 1. User Documentation + +This section is for those interacting with a live instance of the Application. + +### 1.1 Adding the Bot + +Callista is available as a Discord user-installable application. You can add Callista to your Discord account by visiting: +https://discord.com/oauth2/authorize?client_id=1391494389477412906 + +### 1.2 Bookmarking Messages + +To bookmark a message: + +1. Right-click (or long-press on mobile) any message in a guild or private channel +2. Navigate to Apps → Bookmark +3. Callista will send you a DM containing the message link + +**Note:** You must have Direct Messages enabled to receive bookmarks. If you receive an error, check your Discord privacy settings. + +### 1.3 Adding Notes to Bookmarks + +Each bookmark can have an associated note to help you remember context: + +1. When you receive a bookmark DM, click the **Add Note** button +2. A modal will appear asking "What would you like to note down?" +3. Enter your note (1-1000 characters) +4. Your note will be appended to the bookmark message + +### 1.4 Editing Notes + +To edit an existing note on a bookmark: + +1. Click the **Edit Note** button on the bookmark message +2. Update the note text in the modal +3. The bookmark message will be updated with your new note + +### 1.5 Deleting Bookmarks + +To delete a bookmark from your DMs: + +1. Right-click the bookmark message in your DM with Callista +2. Navigate to Apps → Delete +3. The bookmark message will be deleted + +**Note:** The Delete command only works in DMs with Callista (bot DM context). + +### 1.6 Additional Features + +Each bookmark message includes convenient buttons: +- **Add Note/Edit Note**: Add or modify notes on your bookmarks +- **Join our Discord**: Link to the support server (https://chat.nhcarrigan.com) +- **Donate**: Premium button for supporting the bot developer + +### 1.7 Command Reference + +| Command | Type | Context | Description | +|---------|------|---------|-------------| +| Bookmark | Message Context Menu | Guilds, Private Channels | Sends you a DM with the message link | +| Delete | Message Context Menu | Bot DMs | Deletes the bookmark message | + +## 2. Technical Documentation + +This section is for those interested in running their own instance of the Application. + +### 2.1 Prerequisites + +- Node.js (compatible with version specified in package.json) +- pnpm 10.17.1 or higher (specified in packageManager field) +- A Discord Bot Token +- 1Password CLI (op) for production environment variables (or modify start script) + +### 2.2 Dependencies + +**Runtime Dependencies:** +- `discord.js` (14.22.1): Discord API wrapper +- `@nhcarrigan/logger` (1.0.0): Logging utility +- `fastify` (5.6.1): Web server for health monitoring + +**Development Dependencies:** +- TypeScript (5.9.2) +- ESLint with @nhcarrigan configuration +- tsx for development execution + +### 2.3 Installation + +1. Clone the repository: + ```bash + git clone + cd callista + ``` + +2. Install dependencies: + ```bash + pnpm install + ``` + +3. Create a production environment file (`prod.env`) with the following: + ``` + BOT_TOKEN=your_discord_bot_token + ``` + +4. Register Discord commands by running: + ```bash + node commandData.js + ``` + Copy the output JSON and register it via the Discord Developer Portal or API. + +### 2.4 Building + +Compile TypeScript to JavaScript: +```bash +pnpm run build +``` + +Output is generated in the `prod/` directory. + +### 2.5 Running + +**Production:** +```bash +pnpm start +``` + +This uses 1Password CLI to inject environment variables. Modify the start script in `package.json` if using a different secrets management solution. + +**Development:** +```bash +tsx src/index.ts +``` + +### 2.6 Architecture Overview + +**Project Structure:** +``` +src/ +├── index.ts # Main entry point, Discord client setup +├── server/ +│ └── serve.ts # Fastify web server for health checks (port 6111) +├── interactions/ +│ ├── bookmark.ts # Bookmark command handler +│ └── deleteCmd.ts # Delete command handler +├── buttons/ +│ ├── addNote.ts # Add note button definition +│ ├── editNote.ts # Edit note button definition +│ ├── discord.ts # Discord invite button +│ └── donate.ts # Premium donation button +├── modals/ +│ └── note.ts # Note input modal definition +└── utils/ + └── logger.ts # Logger configuration +``` + +**Component Interactions:** + +1. **Discord Client** (`index.ts:22-24`): Initialized with no intents (interaction-only bot) +2. **Interaction Handler** (`index.ts:27-81`): Routes interactions to appropriate handlers +3. **Web Server** (`server/serve.ts:54-79`): Runs on port 6111 for health monitoring +4. **Message Context Commands**: Registered via `commandData.js` with user-install integration + +### 2.7 Bot Configuration + +The bot requires the following Discord application settings: + +**Intents:** None (the bot uses no gateway intents) + +**Integration Types:** +- User Install (ApplicationIntegrationType.UserInstall) + +**Interaction Contexts:** +- Bookmark: Guilds and Private Channels +- Delete: Bot DMs only + +**Commands to Register:** +```json +[ + { + "type": 3, + "name": "Bookmark", + "contexts": [0, 2], + "integration_types": [1] + }, + { + "type": 3, + "name": "Delete", + "contexts": [1], + "integration_types": [1] + } +] +``` + +### 2.8 Environment Variables + +| Variable | Required | Description | +|----------|----------|-------------| +| BOT_TOKEN | Yes | Discord bot token for authentication | + +### 2.9 Monitoring and Health Checks + +The Application exposes a web server on port 6111: +- **Endpoint:** `GET /` +- **Response:** HTML page with bot information +- **Purpose:** Health monitoring and bot information display + +### 2.10 Logging + +Logging is handled via `@nhcarrigan/logger` with the following log levels: +- `debug`: Informational messages (bot online, server started) +- `error`: Error conditions (server failures, etc.) + +Logs are written from `utils/logger.ts:1`. + +### 2.11 Error Handling + +The Application implements error handling for: +- Failed DM delivery (user has DMs disabled) - `interactions/bookmark.ts:43-46` +- Missing message context for modals - `index.ts:46-52` +- Server startup failures - `server/serve.ts:66-77` + +### 2.12 Deployment Considerations + +1. **Port Configuration:** The web server runs on port 6111 by default +2. **Secrets Management:** The default start script uses 1Password CLI +3. **Build Output:** Compiled JavaScript is output to `prod/` directory +4. **Process Management:** Consider using PM2, systemd, or Docker for production + +## 3. Legal Documentation + +This section is for expansions to our legal policies specific to the Application. + +### 3.1 License + +This Application is licensed under **Naomi's Public License** as indicated in the source file headers. + +Copyright held by **NHCarrigan / Naomi Carrigan**. + +Full license text available at: https://docs.nhcarrigan.com/#/license + +### 3.2 Privacy + +Privacy policy document: `PRIVACY.md` in the repository root. + +**Data Collection:** The Application processes the following user data: +- Discord User IDs (for DM delivery) +- Message URLs (bookmarked messages) +- User-provided notes (stored in Discord messages) + +**Data Storage:** All data is stored within Discord's infrastructure via message content. The Application does not maintain a separate database. + +**Data Retention:** Data persists as long as users keep their DM messages. Users can delete bookmarks at any time using the Delete command. + +### 3.3 Terms of Service + +Terms of service document: `TERMS.md` in the repository root. + +### 3.4 Security + +Security policy document: `SECURITY.md` in the repository root. + +For security concerns, please follow the reporting procedures outlined in the security policy. + +### 3.5 Code of Conduct + +Code of conduct document: `CODE_OF_CONDUCT.md` in the repository root. + +## 4. Contributing Documentation + +This section is for documentation related to contributing to the Application's codebase. + +### 4.1 Contributing Guidelines + +Contributing guidelines document: `CONTRIBUTING.md` in the repository root. + +Before contributing, please review: +1. The Code of Conduct (`CODE_OF_CONDUCT.md`) +2. The Contributing Guidelines (`CONTRIBUTING.md`) +3. The License terms (`LICENSE.md`) + +### 4.2 Development Setup + +1. Fork the repository +2. Clone your fork +3. Install dependencies: `pnpm install` +4. Create a Discord application and bot at https://discord.com/developers/applications +5. Copy your bot token to a `prod.env` file (or use environment variables directly) +6. Run the development server: `tsx src/index.ts` + +### 4.3 Code Standards + +The project uses: +- **TypeScript** (5.9.2) with strict type checking +- **ESLint** with `@nhcarrigan/eslint-config` (5.2.0) +- **TypeScript Config** from `@nhcarrigan/typescript-config` (4.0.0) + +Run linting with: +```bash +pnpm run lint +``` + +**Note:** The lint script uses `--max-warnings 0`, so warnings are treated as errors. + +### 4.4 Code Style Notes + +- All source files include copyright headers with `@copyright`, `@license`, and `@author` tags +- Some ESLint rules are selectively disabled with comments (e.g., `index.ts:26`) +- The project uses ESM (module) syntax (`"type": "module"` in package.json) + +### 4.5 Testing + +Currently, the project has a placeholder test script: +```bash +pnpm test +``` + +This exits with code 0 (no tests configured yet). + +### 4.6 Pull Request Process + +1. Create a feature branch from `main` +2. Make your changes following the code standards +3. Run `pnpm run lint` to ensure code quality +4. Run `pnpm run build` to verify the build succeeds +5. Submit a pull request with a clear description of changes +6. Address any review feedback + +### 4.7 Adding New Features + +**Adding a new button:** +1. Create a new file in `src/buttons/` exporting a `ButtonBuilder` +2. Import and add the button to the relevant `ActionRowBuilder` in `index.ts` +3. Add handler logic in `handleInteraction` if the button requires custom behavior + +**Adding a new command:** +1. Create a handler in `src/interactions/` +2. Add the command definition to `commandData.js` +3. Run `node commandData.js` and register the output with Discord +4. Add the command routing logic to `handleInteraction` in `index.ts` + +**Adding a new modal:** +1. Create modal definition in `src/modals/` +2. Add modal handling logic in the `isModalSubmit` section of `handleInteraction` +3. Link the modal to a button or command that calls `showModal()` + +### 4.8 Repository Information + +- **Main Branch:** `main` +- **Package Manager:** pnpm (lockfile version: 10.17.1) +- **CI/CD:** Configuration available in `.gitea/` directory +- **Editor Configuration:** VSCode settings in `.vscode/` + +### 4.9 Contact + +For questions or support: +- **Support Server:** https://chat.nhcarrigan.com +- **Email:** contact@nhcarrigan.com +- **Documentation:** https://docs.nhcarrigan.com/ +- **Source Code:** https://git.nhcarrigan.com/nhcarrigan/callista + +### 4.10 Issue Reporting + +Please report bugs and feature requests via GitHub/Gitea issues at: +https://git.nhcarrigan.com/nhcarrigan/callista + +Include: +- Clear description of the issue or feature +- Steps to reproduce (for bugs) +- Expected vs actual behavior +- Environment details (Discord client version, etc.)