claude updates
This commit is contained in:
194
CLAUDE.md
194
CLAUDE.md
@@ -4,11 +4,12 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|||||||
|
|
||||||
## Project Overview
|
## Project Overview
|
||||||
|
|
||||||
Deskmeter is a productivity tool that measures time spent across desktop workspaces. It consists of three main components:
|
Deskmeter is a productivity tool that measures time spent across desktop workspaces. It consists of four main components:
|
||||||
|
|
||||||
- **dmcore**: Core tracking daemon (`dmapp/dmcore/main.py`) that monitors active workspace and task changes
|
- **dmcore**: Core tracking daemon (`dmapp/dmcore/main.py`) that monitors active workspace and task changes
|
||||||
- **dmweb**: Flask web application (`dmapp/dmweb/`) for viewing productivity data
|
- **dmweb**: Flask web application (`dmapp/dmweb/`) for viewing productivity data
|
||||||
- **dmfnt**: Angular frontend (`dmapp/dmfnt/`) for enhanced UI (in development)
|
- **dmfnt**: Angular frontend (`dmapp/dmfnt/`) for enhanced UI (in development)
|
||||||
|
- **gnome-extension**: GNOME Shell extension (`gnome-extension/deskmeter-indicator@local/`) that displays current task in the top panel
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
@@ -33,8 +34,18 @@ Deskmeter is a productivity tool that measures time spent across desktop workspa
|
|||||||
**Flask Routes** (`dmapp/dmweb/dm.py`):
|
**Flask Routes** (`dmapp/dmweb/dm.py`):
|
||||||
- `/` - Today's productivity summary
|
- `/` - Today's productivity summary
|
||||||
- `/day/<month>/<day>` - Single day view
|
- `/day/<month>/<day>` - Single day view
|
||||||
- `/calendar` - Monthly calendar view via `dmapp/dmweb/dmcal.py`
|
- `/calendar` - Google Calendar-style task timeline view (daily/weekly/monthly)
|
||||||
|
- `/switches` - Raw switch documents view (daily/weekly/monthly)
|
||||||
|
- `/workmonth` - Monthly calendar showing task totals via `dmapp/dmweb/dmcal.py`
|
||||||
- `/totals` - All-time statistics
|
- `/totals` - All-time statistics
|
||||||
|
- `/api/current_task` - JSON API endpoint returning current task info (for GNOME extension)
|
||||||
|
- `/api/today` - HTML fragment for AJAX updates
|
||||||
|
|
||||||
|
**Task Info API** (`dmapp/dmweb/get_period_times.py`):
|
||||||
|
- `get_current_task_info()` - Retrieves current task ID and path from MongoDB state collection
|
||||||
|
- `get_task_path()` - Resolves task ID to path, with automatic task_history fallback
|
||||||
|
- `get_task_blocks_calendar()` - Groups consecutive switches by task, tracks active/idle time
|
||||||
|
- `get_raw_switches()` - Returns all switch documents for a period
|
||||||
|
|
||||||
## Development Commands
|
## Development Commands
|
||||||
|
|
||||||
@@ -78,12 +89,38 @@ npm run build
|
|||||||
npm run test
|
npm run test
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### GNOME Extension
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd gnome-extension
|
||||||
|
|
||||||
|
# Install extension
|
||||||
|
./install.sh
|
||||||
|
|
||||||
|
# Restart GNOME Shell (X11 only)
|
||||||
|
# Alt+F2 → type 'r' → Enter
|
||||||
|
# (On Wayland: log out and back in)
|
||||||
|
|
||||||
|
# Enable extension
|
||||||
|
gnome-extensions enable deskmeter-indicator@local
|
||||||
|
|
||||||
|
# Update extension after changes
|
||||||
|
./update.sh
|
||||||
|
# Then restart GNOME Shell
|
||||||
|
|
||||||
|
# Debug logs
|
||||||
|
journalctl -f -o cat /usr/bin/gnome-shell
|
||||||
|
|
||||||
|
# Test API endpoint
|
||||||
|
curl http://localhost:10000/api/current_task
|
||||||
|
```
|
||||||
|
|
||||||
### System Setup
|
### System Setup
|
||||||
|
|
||||||
The application requires:
|
The application requires:
|
||||||
- MongoDB running locally
|
- MongoDB running locally
|
||||||
- wmctrl installed (`apt install wmctrl`)
|
- wmctrl installed (`apt install wmctrl`)
|
||||||
- X11 desktop environment (not Wayland)
|
- X11 desktop environment (not Wayland for dmcore; GNOME extension works on both X11/Wayland)
|
||||||
- Python virtual environment recommended
|
- Python virtual environment recommended
|
||||||
|
|
||||||
## Key Configuration
|
## Key Configuration
|
||||||
@@ -92,12 +129,161 @@ The application requires:
|
|||||||
**Work Desktop Mapping**: Configure `work_desktops` dict in `dmapp/dmcore/main.py:13`
|
**Work Desktop Mapping**: Configure `work_desktops` dict in `dmapp/dmcore/main.py:13`
|
||||||
**Timezone**: Set in `dmapp/dmcore/main.py:19` using zoneinfo
|
**Timezone**: Set in `dmapp/dmcore/main.py:19` using zoneinfo
|
||||||
|
|
||||||
|
## Calendar & Switches Visualization
|
||||||
|
|
||||||
|
### Overview
|
||||||
|
|
||||||
|
Two complementary views for analyzing workspace switching patterns:
|
||||||
|
- **Calendar View** (`/calendar`) - Google Calendar-style blocks showing when you worked on each task
|
||||||
|
- **Switches View** (`/switches`) - Granular list of every workspace switch
|
||||||
|
|
||||||
|
Both support daily, weekly, and monthly scopes with navigation.
|
||||||
|
|
||||||
|
### Calendar View Features
|
||||||
|
|
||||||
|
**Visual Design**:
|
||||||
|
- Task blocks positioned at actual times during the day
|
||||||
|
- Each task gets consistent color (HSL hue based on task name hash)
|
||||||
|
- Gradient within each block:
|
||||||
|
- Left side (bright) = active time (Plan/Think/Work workspaces)
|
||||||
|
- Right side (faded) = idle time (Other/Away workspaces)
|
||||||
|
- Gradient split point = active/idle ratio
|
||||||
|
|
||||||
|
**Block Grouping**:
|
||||||
|
- Consecutive switches to same task are merged into blocks
|
||||||
|
- Minimum durations filter micro-switches:
|
||||||
|
- Daily: 60 seconds
|
||||||
|
- Weekly: 5 minutes
|
||||||
|
- Monthly: 10 minutes
|
||||||
|
|
||||||
|
**Data Structure** (`get_task_blocks_calendar()`):
|
||||||
|
```python
|
||||||
|
{
|
||||||
|
'task_id': str,
|
||||||
|
'task_path': str,
|
||||||
|
'start': datetime,
|
||||||
|
'end': datetime,
|
||||||
|
'duration': int, # total seconds
|
||||||
|
'active_seconds': int, # Plan/Think/Work time
|
||||||
|
'idle_seconds': int, # Other/Away time
|
||||||
|
'active_ratio': float # 0.0 to 1.0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Switches View Features
|
||||||
|
|
||||||
|
**Visual Design**:
|
||||||
|
- Each switch row color-coded by task (same colors as calendar)
|
||||||
|
- Border color and background both use task color for visual grouping
|
||||||
|
- Active workspaces (Plan/Think/Work) shown bold
|
||||||
|
- Idle workspaces (Other/Away) shown faded
|
||||||
|
|
||||||
|
**Display**:
|
||||||
|
- Timestamp, workspace name, task path, duration for each switch
|
||||||
|
- Stats summary showing total switches and total time
|
||||||
|
- All switches in chronological order
|
||||||
|
|
||||||
|
### Task History System
|
||||||
|
|
||||||
|
**Problem**: Historic task IDs (from archived task files) display as raw IDs instead of paths.
|
||||||
|
|
||||||
|
**Solution**: Automatic on-demand task resolution via `task_history` collection:
|
||||||
|
|
||||||
|
1. When displaying unknown task ID, `get_task_path()` tries:
|
||||||
|
- Current `tasks` collection (active tasks from `main` file)
|
||||||
|
- `task_history` collection (cached historic tasks)
|
||||||
|
- File scan: searches all files in `/home/mariano/LETRAS/adm/task/`
|
||||||
|
2. When found via file scan, stores in `task_history` for next time
|
||||||
|
3. Returns task_id as fallback if not found anywhere
|
||||||
|
|
||||||
|
**Benefits**:
|
||||||
|
- No manual history loading required
|
||||||
|
- No dmcore startup overhead
|
||||||
|
- History populates automatically as you view old data
|
||||||
|
- Frontend self-sufficient and independent
|
||||||
|
|
||||||
|
**Files**:
|
||||||
|
- Frontend parsing: `dmapp/dmweb/get_period_times.py:parse_task_line()`
|
||||||
|
- File scanning: `dmapp/dmweb/get_period_times.py:load_task_from_files()`
|
||||||
|
- Resolution: `dmapp/dmweb/get_period_times.py:get_task_path()`
|
||||||
|
|
||||||
|
## Component Integration
|
||||||
|
|
||||||
|
### How Task Updates Flow
|
||||||
|
|
||||||
|
1. **User switches workspace** → GNOME detects immediately
|
||||||
|
2. **dmcore polling** (every 2 seconds) → detects workspace change via `wmctrl`
|
||||||
|
3. **Task enforcement** → dmcore updates MongoDB state collection with current task
|
||||||
|
4. **GNOME extension** → listens to `workspace-switched` signal, waits 2.2s, queries API
|
||||||
|
5. **Panel indicator updates** → shows current task path in top panel
|
||||||
|
|
||||||
|
### GNOME Extension Architecture
|
||||||
|
|
||||||
|
**Location**: `gnome-extension/deskmeter-indicator@local/`
|
||||||
|
|
||||||
|
**Files**:
|
||||||
|
- `extension.js` - Main extension logic, workspace switch listener, API polling
|
||||||
|
- `metadata.json` - Extension metadata (GNOME 40-47 compatible)
|
||||||
|
- `stylesheet.css` - Panel indicator styling
|
||||||
|
|
||||||
|
**Behavior**:
|
||||||
|
- Connects to GNOME's `workspace-switched` signal
|
||||||
|
- Debounces updates by 2.2 seconds after workspace switch
|
||||||
|
- Queries `/api/current_task` endpoint
|
||||||
|
- Displays task path in panel, truncates if > 40 chars
|
||||||
|
- Shows last 2 path segments for long paths (e.g., `.../work/project`)
|
||||||
|
|
||||||
|
**Update Workflow**:
|
||||||
|
1. Edit source files in `gnome-extension/deskmeter-indicator@local/`
|
||||||
|
2. Run `./update.sh` to copy to `~/.local/share/gnome-shell/extensions/`
|
||||||
|
3. Restart GNOME Shell (`Alt+F2` → `r` on X11, or log out/in on Wayland)
|
||||||
|
4. Check logs: `journalctl -f -o cat /usr/bin/gnome-shell`
|
||||||
|
|
||||||
## Development Notes
|
## Development Notes
|
||||||
|
|
||||||
- The system enforces task constraints within work desktops - switching to a non-work task automatically reverts to the designated work task
|
- The system enforces task constraints within work desktops - switching to a non-work task automatically reverts to the designated work task
|
||||||
- Task files are monitored for changes to enable automatic context switching
|
- Task files are monitored for changes to enable automatic context switching
|
||||||
- Web interface runs on port 10000 by default
|
- Web interface runs on port 10000 by default
|
||||||
- Core daemon sleeps for 2 seconds between workspace checks
|
- Core daemon sleeps for 2 seconds between workspace checks
|
||||||
|
- GNOME extension debounce delay (2.2s) must be > dmcore polling interval (2s) to ensure MongoDB is updated before API query
|
||||||
|
|
||||||
|
## Working on Calendar/Switches Views
|
||||||
|
|
||||||
|
### Current Implementation
|
||||||
|
|
||||||
|
**Routes** (`dmapp/dmweb/dm.py`):
|
||||||
|
- `/calendar` and `/switches` must be defined BEFORE the catch-all `/<string:task>` route
|
||||||
|
- Both support `/<scope>` (daily/weekly/monthly) and `/<scope>/<year>/<month>/<day>`
|
||||||
|
- Navigation via prev/next date links and tab switching between scopes
|
||||||
|
|
||||||
|
**Templates**:
|
||||||
|
- `calendar_view.html` - 24-hour grid with task blocks positioned by time
|
||||||
|
- `switches_view.html` - Simple list with task-based color coding
|
||||||
|
- Both use Jinja2 `|hash` filter for color generation (registered in `__init__.py`)
|
||||||
|
|
||||||
|
**Data Flow**:
|
||||||
|
1. Route extracts date range from URL params
|
||||||
|
2. Calls `get_task_blocks_calendar()` or `get_raw_switches()`
|
||||||
|
3. Each function calls `get_task_path()` for task name resolution
|
||||||
|
4. `get_task_path()` auto-populates `task_history` on cache miss
|
||||||
|
5. Template renders with inline styles (HSL colors from task name hash)
|
||||||
|
|
||||||
|
### Potential Improvements
|
||||||
|
|
||||||
|
- **Performance**: Cache `get_task_path()` results in-memory to avoid repeated DB lookups
|
||||||
|
- **Color collision**: Current hash % 360 can produce similar hues for different tasks
|
||||||
|
- **Weekly/monthly calendar**: Currently shows sequential blocks, could show multi-column grid like daily view
|
||||||
|
- **Task filtering**: Add URL param to filter by specific task(s)
|
||||||
|
- **Export**: Add CSV/JSON export of block or switch data
|
||||||
|
- **Overlapping blocks**: If switching between tasks within same hour, blocks could overlap visually
|
||||||
|
|
||||||
|
### Key Design Decisions
|
||||||
|
|
||||||
|
1. **No JavaScript frameworks** - Pure server-rendered HTML with minimal CSS transitions
|
||||||
|
2. **Task history is frontend-only** - dmcore never touches task_history collection
|
||||||
|
3. **Color coding consistency** - Same task always gets same color across all views
|
||||||
|
4. **Gradient indicates work quality** - Visual distinction between active focus and idle time
|
||||||
|
5. **Multiple thresholds** - Different minimum block durations for different scopes reduces noise
|
||||||
|
|
||||||
## Tool Development Guidelines
|
## Tool Development Guidelines
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user