From 4cc15a96fec98dc12197c348068e7df62d315133 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 16 Apr 2026 08:34:32 +0000 Subject: [PATCH] docs: sync markdown documentation with codebase - CLAUDE.md: add last_sync field to WorkspaceConfig description - README.md: update Phase 4 status, replace dark mode with multi-theme system, add has_time/parent fields to data format example - PLAN.md: add last_sync to Phase 1 WorkspaceConfig, update dark mode entries to reflect theme selector, fix Google Tasks Tauri command names, add rename_list/move_task to Core Library API, fix "Move to..." description (inline, not submenu) - docs/API.md: document rename_list and move_task repository methods - docs/DEVELOPMENT.md: add dateFormat.ts to frontend file structure https://claude.ai/code/session_01NCtJ5PNhaDh21kYnDZXYsN --- CLAUDE.md | 2 +- PLAN.md | 11 +++++++---- README.md | 6 ++++-- docs/API.md | 12 ++++++++++++ docs/DEVELOPMENT.md | 1 + 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 5b915fb..c19aa6d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -37,7 +37,7 @@ Two-crate workspace (`resolver = "2"`, edition 2021) plus a Tauri app: - **Storage trait** (`storage.rs`): Strategy pattern for task persistence. `FileSystemStorage` reads/writes markdown files with YAML frontmatter and JSON metadata files. Atomic writes (temp file + rename, with temp cleanup on failure) for all metadata files. Input validation: task titles max 500 chars, descriptions max 1MB, list names max 255 chars, YAML frontmatter max 64KB. Delete operations update metadata before removing files to prevent orphaned metadata on crash. - **Repository** (`repository.rs`): `TaskRepository` wraps a `Storage` impl and provides the public API for task/list CRUD, ordering, and grouping. Tests live here. -- **Config** (`config.rs`): `AppConfig` manages workspaces keyed by UUID string. `WorkspaceConfig` stores `name`, `path`, `mode` (Local/Webdav/GoogleTasks), `webdav_url`, `webdav_path` (user-selected remote folder), `google_account` (display name/email for GoogleTasks workspaces), `theme`, `sync_interval_secs` (focused polling interval), and `sync_interval_unfocused_secs` (lower-frequency polling when window loses focus, for mobile battery optimization). `add_workspace` returns a generated UUID. Stored in platform-specific config dirs via the `directories` crate. Atomic writes (temp file + rename) prevent corruption on crash. +- **Config** (`config.rs`): `AppConfig` manages workspaces keyed by UUID string. `WorkspaceConfig` stores `name`, `path`, `mode` (Local/Webdav/GoogleTasks), `webdav_url`, `webdav_path` (user-selected remote folder), `google_account` (display name/email for GoogleTasks workspaces), `last_sync` (timestamp of last successful sync), `theme`, `sync_interval_secs` (focused polling interval), and `sync_interval_unfocused_secs` (lower-frequency polling when window loses focus, for mobile battery optimization). `add_workspace` returns a generated UUID. Stored in platform-specific config dirs via the `directories` crate. Atomic writes (temp file + rename) prevent corruption on crash. - **Sync** (`sync.rs`): Three-way diff sync with offline queue. File-based `.sync.lock` prevents concurrent sync operations (auto-cleaned after 5 minutes if stale). Checksum-based conflict resolution: downloads remote, compares SHA-256 — identical content is a false conflict (skipped); when different, remote wins and local is recovered as a duplicate with a new UUID and `[RECOVERED FROM CONFLICT]` prefix (duplicate file cleaned up if metadata update fails). Auto-sync lifecycle: periodic polling (configurable interval, default 60s), debounced file-change (5s), window-focus (30s stale threshold). Wrapped in `tokio::time::timeout` (60s) to handle unreachable servers on Windows. Path traversal validation rejects `..` components and backslashes anywhere in sync paths. Atomic writes for sync state and queue files (temp cleanup on failure). - **WebDAV** (`webdav.rs`): reqwest client with rustls-tls, 30s request timeout, 10s connect timeout. Rejects non-HTTPS URLs. `Zeroizing` for credential fields. `move_resource` method for WebDAV MOVE (workspace rename). 10MB cap on both PROPFIND responses and file downloads. Desktop credentials via `keyring` crate (feature-gated); Tauri GUI uses `tauri-plugin-credentials` for cross-platform support (Android Keystore + desktop keychain). - **Google Tasks** (`google_tasks.rs`): Read-only Google Tasks API client using reqwest with Bearer auth. `gt_id_to_uuid()` converts Google Task IDs to stable UUID v5 values for consistent cross-sync identity. Fetches all task lists and tasks from the Google Tasks REST API and writes them locally via `FileSystemStorage`. Remote always wins (read-only workspace mode). OAuth flow is partially implemented — client ID/secret are placeholders pending real credentials. diff --git a/PLAN.md b/PLAN.md index c19f9c7..8c9893e 100644 --- a/PLAN.md +++ b/PLAN.md @@ -123,6 +123,7 @@ WorkspaceConfig { webdav_url: Option, webdav_path: Option, // User-selected remote folder google_account: Option, // Email/display name (GoogleTasks workspaces) + last_sync: Option, // Timestamp of last successful sync theme: Option, sync_interval_secs: Option, // Auto-sync polling interval (focused) sync_interval_unfocused_secs: Option, // Auto-sync interval when unfocused @@ -223,6 +224,8 @@ impl TaskRepository { pub fn get_lists(&self) -> Result>; pub fn get_list(&self, list_id: Uuid) -> Result; pub fn delete_list(&mut self, id: Uuid) -> Result<()>; + pub fn rename_list(&mut self, list_id: Uuid, new_name: String) -> Result<()>; + pub fn move_task(&mut self, from_list_id: Uuid, to_list_id: Uuid, task_id: Uuid) -> Result<()>; // Task ordering (modifies .listdata.json) pub fn reorder_task(&mut self, list_id: Uuid, task_id: Uuid, new_position: usize) -> Result<()>; @@ -750,10 +753,10 @@ WorkspaceConfig { - [x] Mark tasks complete/incomplete with animated transitions - [x] Drag-and-drop task reordering - [x] Sliding lists drawer (80cqi wide, left side) -- [x] Settings popup overlay (WebDAV config, dark mode toggle) -- [x] Dark mode (GNOME-style neutral theme, cyan-blue accent) +- [x] Settings popup overlay (WebDAV config, theme selector) +- [x] Per-workspace theme system (System default, Light, Dark, Nord, Dracula, Solarized Dark, Ink) - [x] Animated completed section show/hide -- [x] Move task between lists (kebab menu → "Move to..." submenu in task detail view) +- [x] Move task between lists (kebab menu → "Move to..." inline list in task detail view, not a submenu) - [x] Optional time on due dates (`has_time: bool` field on Task with `#[serde(default)]` for backward compat; replaces the hours==0 heuristic) - [x] Due date picker/editor (DateTimePicker component in both new task toast + task detail view) - [x] WebDAV setup flow with credentials (settings auto-populates URL/username/password from config + keychain on open) @@ -977,7 +980,7 @@ npm run tauri ios build #### Google Tasks Importer - [x] `google_tasks.rs` module in `onyx-core` — client, UUID mapping, read-only sync (remote always wins) - [x] `GoogleTasks` workspace mode and `google_account` config field -- [x] Tauri commands: `google_tasks_authorize()`, `google_tasks_sync()` +- [x] Tauri commands: `start_google_oauth()`, `add_google_tasks_workspace()`, `sync_google_tasks_workspace()` - [ ] Complete OAuth flow (client ID/secret placeholders need real credentials) - [ ] Migrate tasks, lists, due dates, notes with full UI integration - [ ] Preserve task hierarchy and order diff --git a/README.md b/README.md index c2438aa..0b255a3 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ onyx/ - **Phase 1** (Core + CLI): Complete - **Phase 2** (WebDAV Sync): Complete — backend, CLI, and GUI all wired - **Phase 3** (GUI MVP): Complete -- **Phase 4** (Mobile): Tauri Android cfg-gated, needs `tauri android init` + build +- **Phase 4** (Mobile): In progress — Android preliminaries done (file-watcher gating, tauri-plugin-credentials, safe area insets, Android targets configured); needs build verification and iOS setup ### Core Library (`onyx-core`) - Data models (Task, TaskList, AppConfig, WorkspaceConfig) @@ -55,7 +55,7 @@ onyx/ - Drag-and-drop reordering - Sliding lists drawer, settings popup - Workspace switcher with add/remove -- Dark mode (GNOME-style neutral grays, cyan-blue accent) +- Per-workspace theme system (System default, Light, Dark, Nord, Dracula, Solarized Dark, Ink) - Due date picker/editor with optional time - Subtask hierarchy with three-panel slide navigation - Move tasks between lists @@ -169,6 +169,8 @@ id: 550e8400-e29b-41d4-a716-446655440000 status: backlog version: 3 date: 2026-11-15T14:00:00Z +has_time: true +parent: 550e8400-e29b-41d4-a716-446655440001 --- Task description and notes go here in **markdown** format. diff --git a/docs/API.md b/docs/API.md index 2be2283..011997c 100644 --- a/docs/API.md +++ b/docs/API.md @@ -207,6 +207,18 @@ let list = repo.get_list(list_id)?; repo.delete_list(list_id)?; ``` +#### Rename List + +```rust +repo.rename_list(list_id, "New Name".to_string())?; +``` + +#### Move Task Between Lists + +```rust +repo.move_task(from_list_id, to_list_id, task_id)?; +``` + ### Task Ordering #### Reorder Task diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index 3248023..e1616b7 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -76,6 +76,7 @@ onyx/ │ │ ├── screens/ # Full-page views │ │ ├── components/ # Reusable UI components │ │ ├── stores/ # Svelte state (app.svelte.ts) +│ │ ├── dateFormat.ts # Date formatting utilities │ │ └── types.ts # TypeScript type definitions │ ├── tauri-plugin-credentials/ # Cross-platform credential storage plugin │ │ ├── Cargo.toml