17 KiB
LUK Project Plan
This document outlines planned improvements across the LUK applications (Mail, Calendar, Sync, Tasks).
Bug Fixes
Tasks App - Table Not Displaying (FIXED)
Priority: Critical
File: src/tasks/app.py
The tasks app was not showing the task table due to a CSS grid layout issue. The grid layout with mixed dock and grid positioning caused the main content area to have 0 height.
Fix: Changed from grid layout to horizontal layout with docked header/footer.
Sync App
Performance Improvements
1. Parallelize Message Downloads
Priority: High
Files: src/services/microsoft_graph/mail.py, src/services/microsoft_graph/client.py
Currently, message downloads are sequential (for loop with await). This is a significant bottleneck.
Current code pattern:
for msg_id in message_ids:
content = await client.get_message(msg_id)
await save_to_maildir(content)
Proposed changes:
- Increase semaphore limit in
client.pyfrom 2 to 5 concurrent HTTP requests - Batch parallel downloads using
asyncio.gather()with batches of 5-10 messages - Batch sync state writes every N messages instead of after each message (currently an I/O bottleneck in archive sync)
Example implementation:
BATCH_SIZE = 5
async def fetch_batch(batch_ids):
return await asyncio.gather(*[client.get_message(id) for id in batch_ids])
for i in range(0, len(message_ids), BATCH_SIZE):
batch = message_ids[i:i + BATCH_SIZE]
results = await fetch_batch(batch)
for content in results:
await save_to_maildir(content)
# Write sync state every batch instead of every message
save_sync_state()
2. Optimize Maildir Writes
Priority: Medium
File: src/utils/mail_utils/maildir.py
The save_mime_to_maildir_async function is a potential bottleneck. Consider:
- Batching file writes
- Using thread pool for I/O operations
CLI Improvements
3. Default to TUI Mode
Priority: Medium
File: src/cli/sync.py
Currently luk sync requires subcommands. Change to:
luk sync→ Opens TUI (interactive mode) by defaultluk sync --once/luk sync -1→ One-shot syncluk sync --daemon/luk sync -d→ Daemon modeluk sync status→ Show sync status
UI Consistency
4. Navigation and Styling
Priority: Low
File: src/cli/sync_dashboard.py
- Add
j/kkeybindings for list navigation (vim-style) - Use
border: roundin TCSS for consistency with other apps - Add
.border_titlestyling for list containers
5. Notifications Toggle
Priority: Low
Files: src/cli/sync_dashboard.py, src/utils/notifications.py
Add a UI switch to enable/disable desktop notifications during sync.
Inter-Process Communication (IPC)
Overview
Priority: High
Goal: Enable real-time updates between apps when data changes:
- Mail app refreshes when sync downloads new messages
- Tasks app refreshes when syncing or when tasks are added from mail app
- Calendar app reloads when sync updates events
Platform Options
macOS Options
-
Distributed Notifications (NSDistributedNotificationCenter)
- Native macOS IPC mechanism
- Simple pub/sub model
- Lightweight, no server needed
- Python: Use
pyobjc(Foundation.NSDistributedNotificationCenter) - Example:
CFNotificationCenterPostNotification()
-
Unix Domain Sockets
- Works on both macOS and Linux
- Requires a listener process (daemon or embedded in sync)
- More complex but more flexible
- Can send structured data (JSON messages)
-
Named Pipes (FIFO)
- Simple, works on both platforms
- One-way communication
- Less suitable for bidirectional messaging
-
File-based Signaling
- Write a "dirty" file that apps watch via
watchdogorfsevents - Simple but has latency
- Works cross-platform
- Write a "dirty" file that apps watch via
Linux Options
-
D-Bus
- Standard Linux IPC
- Python: Use
dbus-pythonorpydbus - Powerful but more complex
- Not available on macOS by default
-
Unix Domain Sockets
- Same as macOS, fully compatible
- Recommended for cross-platform compatibility
-
systemd Socket Activation
- If running as a systemd service
- Clean integration with Linux init
Recommended Approach
Use Unix Domain Sockets for cross-platform compatibility:
# Socket path
SOCKET_PATH = Path.home() / ".cache" / "luk" / "ipc.sock"
# Message types
class IPCMessage:
MAIL_UPDATED = "mail.updated"
TASKS_UPDATED = "tasks.updated"
CALENDAR_UPDATED = "calendar.updated"
# Sync daemon sends notifications
async def notify_mail_updated(folder: str):
await send_ipc_message({"type": IPCMessage.MAIL_UPDATED, "folder": folder})
# Mail app listens
async def listen_for_updates():
async for message in ipc_listener():
if message["type"] == IPCMessage.MAIL_UPDATED:
self.load_messages()
Implementation files:
src/utils/ipc.py- IPC client/server utilitiessrc/cli/sync_daemon.py- Add notification sendingsrc/mail/app.py- Add listener for mail updatessrc/tasks/app.py- Add listener for task updatessrc/calendar/app.py- Add listener for calendar updates
Calendar App
Visual Improvements
1. Current Time Hour Line Styling
Priority: High
File: src/calendar/widgets/WeekGrid.py
The current time indicator hour line should have a subtle contrasting background color to make it more visible.
2. Cursor Hour Header Highlighting
Priority: Medium
File: src/calendar/widgets/WeekGrid.py
The hour header at cursor position should have a brighter background, similar to how the day header is highlighted when selected.
Layout Improvements
3. Responsive Detail Panel
Priority: Medium
Files: src/calendar/app.py, src/calendar/widgets/
When the terminal is wider than X characters (e.g., 120), show a side-docked detail panel for the selected event instead of a modal/overlay.
4. Sidebar Mini-Calendar
Priority: Medium
Files: src/calendar/app.py, src/calendar/widgets/MonthCalendar.py
When the sidebar is toggled on, display a mini-calendar in the top-left corner showing:
- Current day highlighted
- The week(s) currently visible in the main WeekGrid pane
- Click/navigate to jump to a specific date
Implementation:
- Reuse existing
MonthCalendarwidget in compact mode - Add reactive property to sync selected week with main pane
- Add to sidebar composition when toggled
Microsoft Graph Integration
5. Calendar Invites Sidebar
Priority: Medium
Files: src/calendar/app.py, src/services/microsoft_graph/calendar.py
Display a list of pending calendar invites from Microsoft Graph API in a sidebar panel:
- List pending invites (meeting requests)
- Show invite details (organizer, time, subject)
- Accept/Decline/Tentative actions
- No sync needed - fetch on-demand from API
API Endpoints:
GET /me/calendar/events?$filter=responseStatus/response eq 'notResponded'POST /me/events/{id}/acceptPOST /me/events/{id}/declinePOST /me/events/{id}/tentativelyAccept
UI:
- Toggle with keybinding (e.g.,
ifor invites) - Sidebar shows list of pending invites
- Detail view shows full invite info
- Action buttons/keys for response
Search Feature
6. Calendar Search
Priority: Medium
Files: src/calendar/app.py, src/services/khal/client.py (if khal supports search)
Add search functionality if the underlying backend (khal) supports it:
/keybinding to open search input- Search by event title, description, location
- Display search results in a modal or replace main view
- Navigate to selected event
Check: Does khal search command exist?
Help System
7. Help Toast (Keep Current Implementation)
Priority: Low
File: src/calendar/app.py
The ? key shows a help toast using self.notify(). This pattern should be implemented in other apps (Mail, Tasks, Sync) for consistency.
Mail App
Layout Fixes
1. Remove Envelope Icon/Checkbox Gap
Priority: High
File: src/mail/widgets/EnvelopeListItem.py
There's a 1-character space between the envelope icon and checkbox that should be removed for tighter layout.
Theme Improvements
2. Replace Hardcoded RGB Colors
Priority: High
File: src/mail/email_viewer.tcss
Multiple hardcoded RGB values should use Textual theme variables for better theming support:
| Line | Current | Replacement |
|---|---|---|
| 6 | border: round rgb(117, 106, 129) |
border: round $border |
| 46 | background: rgb(55, 53, 57) |
background: $surface |
| 52, 57 | RGB label colors | Theme variables |
| 69 | background: rgb(64, 62, 65) |
background: $panel |
| 169, 225, 228, 272, 274 | Various RGB colors | Theme variables |
Keybindings
3. Add Refresh Keybinding
Priority: Medium
File: src/mail/app.py
Add r keybinding to refresh/reload the message list.
4. Add Mark Read/Unread Action
Priority: Medium
Files: src/mail/app.py, src/mail/actions/ (new file)
Add action to toggle read/unread status on selected message(s).
Search Feature
5. Mail Search
Priority: Medium
Files: src/mail/app.py, backend integration
Add search functionality if the underlying mail backend supports it:
/keybinding to open search input- Search by subject, sender, body
- Display results in message list
- Check: Does himalaya or configured backend support search?
UI Enhancements
6. Folder Message Counts
Priority: Medium
Files: src/mail/app.py, src/mail/widgets/
Display total message count next to each folder name (e.g., "Inbox (42)").
7. Sort Setting in Config/UI
Priority: Low
Files: src/mail/config.py, src/mail/app.py
Add configurable sort order (date, sender, subject) with UI toggle.
Message Display
8. URL Compression in Markdown View
Priority: Medium
Files: src/mail/widgets/ContentContainer.py, src/mail/screens/LinkPanel.py
Compress long URLs in the markdown view to ~50 characters with a nerdfont icon. The _shorten_url algorithm in LinkPanel.py can be reused.
Considerations:
- Cache processed markdown to avoid re-processing on scroll
- Store URL mapping for click handling
9. Remove Emoji from Border Title
Priority: Low
File: src/mail/widgets/ContentContainer.py or EnvelopeHeader.py
Remove the envelope emoji prefix before message ID in border titles.
10. Enhance Subject Styling
Priority: Medium
File: src/mail/widgets/EnvelopeHeader.py
- Move subject line to the top of the header
- Make it bolder/brighter for better visual hierarchy
Tasks App
Search Feature
1. Task Search
Priority: Medium
Files: src/tasks/app.py, src/services/dstask/client.py
Add search functionality:
/keybinding to open search input- Search by task summary, notes, project, tags
- Display matching tasks
- Check: dstask likely supports filtering which can be used for search
Implementation:
- Add search input widget (TextInput)
- Filter tasks locally or via dstask command
- Update table to show only matching tasks
- Clear search with Escape
Help System
2. Implement Help Toast
Priority: Low
File: src/tasks/app.py
Add ? keybinding to show help toast (matching Calendar app pattern).
Note: This is already implemented in the current code.
Cross-App Improvements
1. Consistent Help System
Implement ? key help toast in all apps using self.notify():
- Mail:
src/mail/app.py - Tasks:
src/tasks/app.py(already has it) - Sync:
src/cli/sync_dashboard.py
2. Consistent Navigation
Add vim-style j/k navigation to all list views across apps.
3. Consistent Border Styling
Use border: round and .border_title styling consistently in all TCSS files.
4. Consistent Search Interface
Implement / keybinding for search across all apps with similar UX:
/opens search input- Enter executes search
- Escape clears/closes search
- Results displayed in main view or filtered list
Implementation Priority
Phase 1: Critical/High Priority
Tasks App: Fix table display(DONE)Sync: Parallelize message downloads(DONE - connection pooling + batch size increase)Mail: Replace hardcoded RGB colors(DONE - already using theme variables)Mail: Remove envelope icon/checkbox gap(DONE)Calendar: Current time hour line styling(DONE - added surface background)IPC: Implement cross-app refresh notifications(DONE)
Phase 2: Medium Priority
Sync: Default to TUI mode(DONE - already implemented)Calendar: Cursor hour header highlighting(DONE)- Calendar: Responsive detail panel
- Calendar: Sidebar mini-calendar
- Calendar: Calendar invites sidebar
Mail: Add refresh keybinding(DONE -rkey)Mail: Add mark read/unread action(DONE -ukey)Mail: Folder message counts(DONE)Mail: URL compression in markdown view(DONE)Mail: Enhance subject styling(DONE)- Mail: Search feature
Tasks: Search feature(DONE -/key with live filtering)- Calendar: Search feature
Phase 3: Low Priority
- Sync: UI consistency (j/k navigation, borders)
- Sync: Notifications toggle
- Calendar: Help toast (already implemented, replicate to other apps)
- Mail: Remove emoji from border title
- Mail: Sort setting in config/UI
- Cross-app: Consistent help, navigation, and styling
Technical Notes
IPC Implementation Details
For macOS-first with Linux compatibility:
# src/utils/ipc.py
import asyncio
import json
from pathlib import Path
SOCKET_PATH = Path.home() / ".cache" / "luk" / "ipc.sock"
class IPCServer:
"""Server for sending notifications to listening apps."""
async def broadcast(self, message: dict):
"""Send message to all connected clients."""
pass
class IPCClient:
"""Client for receiving notifications in apps."""
async def listen(self, callback):
"""Listen for messages and call callback."""
pass
Backend Search Capabilities
| Backend | Search Support |
|---|---|
| dstask | Filter by project/tag, summary search via shell |
| himalaya | Check himalaya search command |
| khal | Check khal search command |
| Microsoft Graph | Full text search via $search parameter |
Notes
- All UI improvements should be tested with different terminal sizes
- Theme changes should be tested with multiple Textual themes
- Performance improvements should include before/after benchmarks
- New keybindings should be documented in each app's help toast
- IPC should gracefully handle missing socket (apps work standalone)
- Search should be responsive and not block UI
Library Updates & Python Version Review
Priority: Medium (Scheduled Review)
Periodically review the latest releases of heavily-used libraries to identify:
- Bug fixes that address issues we've encountered
- New features that could improve the codebase
- Deprecation warnings that need to be addressed
- Security updates
Key Libraries to Review
| Library | Current Use | Review Focus |
|---|---|---|
| Textual | All TUI apps | New widgets, performance improvements, theming changes, CSS features |
| aiohttp | Microsoft Graph API client | Async improvements, connection pooling |
| msal | Microsoft authentication | Token caching, auth flow improvements |
| rich | Console output (via Textual) | New formatting options |
| orjson | Fast JSON parsing | Performance improvements |
| pyobjc (macOS) | Notifications | API changes, compatibility |
Textual Changelog Review Checklist
When reviewing Textual releases, check for:
- New widgets - Could replace custom implementations
- CSS features - New selectors, pseudo-classes, properties
- Theming updates - New theme variables, design token changes
- Performance - Rendering optimizations, memory improvements
- Breaking changes - Deprecated APIs, signature changes
- Worker improvements - Background task handling
Python Version Upgrade
Current Status
- Check
.python-versionandpyproject.tomlfor current Python version - Evaluate upgrade to Python 3.13 or 3.14 when stable
Python 3.13 Features to Consider
- Improved error messages
- Type system enhancements (
typingmodule improvements) - Performance optimizations (PEP 709 - inline comprehensions)
Python 3.14 Considerations
- Status: Currently in alpha/beta (as of Dec 2024)
- Expected stable release: October 2025
- Recommendation: Wait for stable release before adopting
- Pre-release testing: Can test compatibility in CI/CD before adoption
Upgrade Checklist
- Review Python release notes for breaking changes
- Check library compatibility (especially
pyobjc,textual,msal) - Update
.python-version(mise/pyenv) - Update
pyproject.tomlrequires-pythonfield - Run full test suite
- Test on both macOS and Linux (if applicable)
- Update CI/CD Python version
Action Items
- Quarterly Review - Schedule quarterly reviews of library changelogs
- Dependabot/Renovate - Consider adding automated dependency update PRs
- Changelog Reading - Before updating, read changelogs for breaking changes
- Test Coverage - Ensure adequate test coverage before major updates