Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,29 @@ Copilot, etc).**

## This is our repo: <https://github.com/timothyfroehlich/DisPinMap>

## 🚨 Issue Awareness - Read First

**CRITICAL**: Before starting any work, review current issues to understand
known problems:

```bash
# 1. List all documented issues
ls docs/issues/*.md

# 2. Get summary of each issue (first 5 lines)
head -5 docs/issues/*.md

# 3. Check GitHub issues (requires gh CLI)
gh issue list --state open

# 4. Review recent closed issues for context
ls docs/issues/closed/*.md 2>/dev/null || echo "No closed issues yet"
```

💡 **Always run these commands to understand the full problem landscape before
starting work. The `head -5` command shows the title and priority/status of each
documented issue.**

## 🗂️ Directory-Specific Agent Instructions

**IMPORTANT**: Before working in any directory, consult its specific CLAUDE.md
Expand Down
126 changes: 126 additions & 0 deletions docs/issues/2-bug-console-interface-limited-commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Console Interface Limited Commands

**Priority**: 2 **Type**: bug **Status**: open **Created**: 2025-07-05
**Updated**: 2025-07-05

## Description

The local development console interface only supports a subset of Discord bot
commands due to hardcoded command mapping instead of using Discord.py's command
processing system.

## Reproduction Steps

1. Start local development: `python local_dev.py`
2. Try commands like `!poll_rate 5` or `!help`
3. Observe "Unknown command" errors
4. Only `!add`, `!list`, `!check`, `!remove` work partially

## Expected vs Actual Behavior

- **Expected**: All Discord bot commands should work in console interface
- **Actual**: Only 5 commands are hardcoded and mapped, others fail with
"Unknown command"

## Technical Details

### Root Cause

The console interface in `src/local_dev/console_discord.py` has an architecture
mismatch:

1. **Hardcoded command mapping**: Only these commands are manually mapped:

```python
if command.startswith("!add"):
await self.command_handler.add_location(fake_message, *command.split()[1:])
elif command.startswith("!list"):
await self.command_handler.list_targets(fake_message)
# etc...
```

2. **Bypasses Discord.py framework**: Should use `bot.process_commands()`
instead
3. **Method name mismatches**: Calls `show_help()` but real method is
`help_command()`

### Missing Commands

- `!poll_rate` - Set polling frequency
- `!notifications` - Configure notification types
- `!export` - Export configuration
- `!monitor_health` - Show monitoring health
- All other commands in `src/cogs/command_handler.py`

### Current Error Examples

```
[CONSOLE] ERROR - ❌ Error processing command '!help': 'CommandHandler' object has no attribute 'show_help'
[CONSOLE] INFO - [BOT] ❓ Unknown command. Available: !add, !list, !check, !remove, !help
```

## Proposed Solution

### Option 1: Use Discord.py Command Processing (Recommended)

Refactor console interface to use `bot.process_commands()`:

```python
async def _process_bot_command(self, command: str):
"""Process command through Discord.py's command system"""
try:
# Create proper fake message object
fake_message = FakeMessage(command)
fake_message.author = FakeUser()
fake_message.channel = FakeChannel()
fake_message.guild = FakeGuild()

# Process through Discord.py command system
await self.bot.process_commands(fake_message)

except Exception as e:
logger.error(f"❌ Error processing command '{command}': {e}")
```

### Option 2: Auto-generate Command Mapping

Dynamically discover and map all commands from loaded cogs:

```python
def _build_command_mapping(self):
"""Build command mapping from all loaded cogs"""
self.command_mapping = {}
for cog_name, cog in self.bot.cogs.items():
for command in cog.get_commands():
self.command_mapping[command.name] = command
```

## Acceptance Criteria

- [ ] All Discord bot commands work in console interface
- [ ] No hardcoded command mapping required
- [ ] Error handling consistent with Discord bot
- [ ] Special console commands (`.quit`, `.status`, etc.) still work
- [ ] Proper fake Discord context objects provided

## Impact

- **Development workflow**: Limited testing capabilities for configuration
commands
- **Debugging**: Cannot test poll rate changes, notification settings via
console
- **User experience**: Confusing that documented commands don't work

## Notes

- Monitoring loop itself works correctly - this is only a console interface
issue
- Commands work fine in actual Discord environment
- Console interface was designed for basic testing, needs expansion for full
functionality

## Related Files

- `src/local_dev/console_discord.py` - Main console interface
- `src/cogs/command_handler.py` - All Discord commands
- `docs/LOCAL_DEVELOPMENT.md` - Documentation of console commands
46 changes: 43 additions & 3 deletions docs/issues/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,23 @@ Clear description of the issue, bug, or feature request.
Additional context, related discussions, or implementation notes.
```

## Directory Structure

```
docs/issues/
├── CLAUDE.md # This documentation
├── <priority>-<type>-<description>.md # Open issues
└── closed/ # Resolved issues archive
└── <priority>-<type>-<description>.md
```

## Workflow

1. **Create Issue**: Document problems/features as they're discovered
2. **Prioritize**: Assign appropriate priority and type
3. **Track Progress**: Update status as work progresses
4. **Close**: Move to closed status when resolved
5. **Archive**: Optionally move closed issues to subdirectories
4. **Close**: Update status to 'closed' and move file to `closed/` directory
5. **Archive**: Use `closed/` directory to maintain history of resolved issues

## Priority Guidelines

Expand Down Expand Up @@ -113,6 +123,35 @@ Additional context, related discussions, or implementation notes.
- Update issue status when work begins/completes
- Use issue analysis to guide development priorities

## Closing and Archiving Issues

### When to Close an Issue

- **Bug fixed**: Code changes resolve the reported problem
- **Feature implemented**: All acceptance criteria are met
- **No longer relevant**: Issue became obsolete due to other changes
- **Duplicate**: Issue already covered by another issue

### Closing Process

1. Update issue status to `closed` in the header
2. Add resolution details to the issue description
3. Move file to `closed/` directory: `git mv issue.md closed/`
4. Reference the closing commit in issue resolution notes

### Example Closure

```markdown
**Status**: closed **Resolved**: 2025-07-05 **Resolution**: Fixed in commit
abc123

## Resolution

Issue resolved by implementing Discord.py command processing in console
interface. All commands now work correctly through `bot.process_commands()`
integration.
```

## AI Agent Guidelines

When working on this project:
Expand All @@ -121,4 +160,5 @@ When working on this project:
2. **Create new issues** for discovered problems
3. **Update issue status** as work progresses
4. **Reference issues** in commits and PRs
5. **Prioritize work** based on issue priorities
5. **Close and archive** resolved issues properly
6. **Prioritize work** based on issue priorities
11 changes: 10 additions & 1 deletion local_dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@
"""

if __name__ == "__main__":
import asyncio
from src.local_dev.local_dev import main

Comment on lines 12 to 15
Copy link

Copilot AI Jul 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider moving import asyncio (and the from src.local_dev.local_dev import main) to the top of the file so that all imports are grouped at module level for consistency.

Suggested change
if __name__ == "__main__":
import asyncio
from src.local_dev.local_dev import main
import asyncio
from src.local_dev.local_dev import main
if __name__ == "__main__":

Copilot uses AI. Check for mistakes.
main()
try:
asyncio.run(main())
except KeyboardInterrupt:
print("\n👋 Goodbye!")
except Exception as e:
print(f"❌ Fatal error: {e}")
Comment on lines +20 to +21
Copy link

Copilot AI Jul 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Printing only the exception message can hide the stack trace; consider using the traceback module or logging to show full context for easier debugging.

Suggested change
except Exception as e:
print(f"❌ Fatal error: {e}")
except Exception:
import traceback
traceback.print_exc()

Copilot uses AI. Check for mistakes.
import sys

Comment on lines +22 to +23
Copy link

Copilot AI Jul 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Importing sys inside the exception block is unconventional; move this import to the top of the file to comply with standard import practices.

Suggested change
import sys

Copilot uses AI. Check for mistakes.
sys.exit(1)
60 changes: 60 additions & 0 deletions scripts/send_command.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/bin/bash
# Script to send commands to the local development bot

# Parse arguments
AUTO_START=true
COMMAND=""

while [[ $# -gt 0 ]]; do
case $1 in
--no-auto-start)
AUTO_START=false
shift
;;
*)
COMMAND="$1"
shift
;;
esac
done

if [ -z "$COMMAND" ]; then
echo "Usage: ./send_command.sh [--no-auto-start] <command>"
echo "Examples:"
echo " ./send_command.sh '!list'"
echo " ./send_command.sh '.status'"
echo " ./send_command.sh '.trigger'"
echo " ./send_command.sh '!check'"
echo " ./send_command.sh --no-auto-start '!list' # Don't start bot automatically"
Comment on lines +22 to +28
Copy link

Copilot AI Jul 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use $(basename "$0") instead of hardcoding send_command.sh in the usage message, so the script remains accurate if renamed or symlinked.

Suggested change
echo "Usage: ./send_command.sh [--no-auto-start] <command>"
echo "Examples:"
echo " ./send_command.sh '!list'"
echo " ./send_command.sh '.status'"
echo " ./send_command.sh '.trigger'"
echo " ./send_command.sh '!check'"
echo " ./send_command.sh --no-auto-start '!list' # Don't start bot automatically"
echo "Usage: $(basename "$0") [--no-auto-start] <command>"
echo "Examples:"
echo " $(basename "$0") '!list'"
echo " $(basename "$0") '.status'"
echo " $(basename "$0") '.trigger'"
echo " $(basename "$0") '!check'"
echo " $(basename "$0") --no-auto-start '!list' # Don't start bot automatically"

Copilot uses AI. Check for mistakes.
exit 1
fi

# Get the project root directory (parent of scripts)
PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"

# Check if bot is running
check_bot_running() {
pgrep -f "python.*local_dev" > /dev/null
}

# Start bot if needed
if ! check_bot_running; then
if [ "$AUTO_START" = true ]; then
echo "Bot not running, starting it..."
cd "$PROJECT_ROOT"
source venv/bin/activate && python local_dev.py > /dev/null 2>&1 &
BOT_PID=$!
echo "Bot started with PID: $BOT_PID"
echo "Waiting 3 seconds for bot to initialize..."
sleep 3
else
echo "Error: Bot is not running. Start it with 'python local_dev.py' or remove --no-auto-start flag"
exit 1
fi
else
echo "Bot is already running"
fi

echo "$COMMAND" >> "$PROJECT_ROOT/commands.txt"
echo "Command sent: $COMMAND"
echo "Monitor responses with: tail -f $PROJECT_ROOT/logs/bot.log"