Add /tasks skill for Google Tasks

- New gtasks skill with thin wrapper around morning-report collector
- Register /tasks command with /todo, /todos aliases
- Design doc at docs/plans/2026-01-05-gtasks-skill-design.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
OpenCode Test
2026-01-05 13:15:15 -08:00
parent 9ae8ff85c3
commit 7e563bd334
4 changed files with 176 additions and 0 deletions

52
skills/gtasks/SKILL.md Normal file
View File

@@ -0,0 +1,52 @@
---
name: gtasks
description: Google Tasks read access — list pending tasks. Use when asked about tasks, todos, or what needs to be done.
allowed-tools:
- Bash
- Read
---
# Google Tasks Skill
List pending Google Tasks. Uses OAuth credentials at `~/.gmail-mcp/`.
## Quick Commands
```bash
GMAIL_PY=~/.claude/mcp/gmail/venv/bin/python
SCRIPTS=~/.claude/skills/gtasks/scripts
# List tasks (default 10)
$GMAIL_PY $SCRIPTS/list.py
# Show more tasks
$GMAIL_PY $SCRIPTS/list.py 20
```
## Script Reference
| Script | Purpose | Args |
|--------|---------|------|
| `list.py` | List pending tasks | `[max]` (default 10) |
## Request Routing
| User Request | Script |
|--------------|--------|
| "What are my tasks?" | `list.py` |
| "Show my todos" | `list.py` |
| "/tasks" | `list.py` |
## Output Format
```
6 pending
• 5:00 PM - Dinner at Lecosho
• 3:00 PM - Snack at Le Panier
• 2:00 PM - Coffee at QED
```
## Policy
- **Read-only** operations only
- **Summarize** results, don't dump raw data

30
skills/gtasks/scripts/list.py Executable file
View File

@@ -0,0 +1,30 @@
#!/usr/bin/env python3
"""List Google Tasks - thin wrapper around morning-report collector."""
import sys
from pathlib import Path
# Import from morning-report collector
sys.path.insert(0, str(Path.home() / ".claude/skills/morning-report/scripts/collectors"))
from gtasks import fetch_tasks, format_tasks
def main():
max_display = int(sys.argv[1]) if len(sys.argv) > 1 else 10
tasks = fetch_tasks(max_results=max_display + 5)
if not tasks:
print("No pending tasks.")
return
# Check for error response
if len(tasks) == 1 and "error" in tasks[0]:
print(f"Error: {tasks[0]['error']}")
return
print(format_tasks(tasks, max_display))
if __name__ == "__main__":
main()