- NotesListView: skeleton shimmer for grid and list modes; grid columns change from fixed 3 to auto-fill(260px)
- NoteCard compact: flat border-bottom row style instead of stacked mini-cards; gradient fade mask on grid preview text
- TaskCard compact: flat border-bottom row style; show up to 2 tags
- TasksListView: gradient + shadow on New Task button (matches NotesListView)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
stores/chat.ts:
- Replace 7 global stream refs with convStreams: Record<number, ConvStreamState>
- Each conversation tracks its own stream state; 7 names become computed getters
- Add isStreamingConv(id) public helper
- Increment message_count +2 immediately after POST 202 (not at done) so the
cleanup watcher never deletes a mid-generation conversation
- SSE reconnect retries now run for background conversations regardless of
which conv is currently viewed
- error toasts only shown when the erroring conv is currently viewed
- deleteConversation cleans up orphaned stream state
ChatView.vue:
- Remove invalid write to store.lastContextMeta (now a read-only computed)
- Add !store.isStreamingConv(newId) guard to watch(convId) fetch so navigating
back to a generating conversation shows accumulated content without stale refetch
- Add startNewConversation() helper; opening /chat with no ID auto-creates a
new conversation and redirects to it (on mount and on navigation)
- Deleting a conversation also auto-creates a new one
Also committing previous-session changes (keyboard nav + task routing):
- App.vue: e shortcut only on note-view (not task-view, which is removed)
- TaskCard.vue: route directly to /tasks/:id (viewer), remove View buttons
- router/index.ts: remove task-view route; /tasks/:id now maps to TaskEditorView
- TasksListView.vue: Enter key pushes to /tasks/:id
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Clicking a task card now goes directly to the edit view since that's
the primary use case. The hover button (compact) and button (full card)
are now labeled "View" and link to the detail/viewer view instead.
Sub-task links in TaskViewerView also route to edit.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
NoteCard: add compact prop — single-row title/tags/timestamp, no body preview
TaskCard: add compact prop — single-row with status dot, priority badge,
title, optional project breadcrumb, due date; edit button appears on hover.
Add projectTitle prop for cross-view context.
NotesListView: auto-fill CSS grid layout (2–4 columns); compact list toggle;
view mode persisted to localStorage.
TasksListView: compact rows throughout; group-by-project toggle with
collapsible sections, task counts, and "Open project" links; fetches
project list for group labels and task breadcrumbs; limit raised to 100
in grouped mode; view mode persisted to localStorage.
HomeView dashboard: task sections use compact rows (project breadcrumb shown);
notes column uses 2-per-row mini-grid; new "Active Projects" widget below
main grid shows milestone progress bars for up to 6 active projects.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend security & correctness:
- Add rate_limit.py: sliding-window rate limiter (asyncio) applied to login,
register, forgot/reset password endpoints (10/60s or 5/300s per IP)
- app.py: add security headers in after_request (X-Frame-Options, CSP,
X-Content-Type-Options, Referrer-Policy) using setdefault to preserve SSE headers
- auth.py: refactor duplicate login_required/admin_required into shared _check_auth()
- config.py: add TRUST_PROXY_HEADERS for proxy-aware client IP resolution
- routes/auth.py: rate limiting, _client_ip() helper, cleaned-up reset_password route
- routes/chat.py, notes.py, tasks.py: int() DoS fix on last_event_id; limit capped
at 500; date.fromisoformat() wrapped in try/except → 400 on invalid dates
- services/auth.py: fix Setting.user_id update bug (filter on NULL not user.id);
reset_password_with_token returns int|None (user_id) instead of bool
- services/backup.py: add _security_notice to full backup JSON export
- services/assist.py: system prompt explicitly preserves markdown list structure
and nested indented sub-items
Infrastructure:
- docker-compose.yml: add healthcheck on app service (/api/health, 10s interval)
- .dockerignore: prevent secrets/node_modules/__pycache__/.env.* leaking into build
Frontend bug fixes:
- TaskCard.vue, TaskViewerView.vue: fix isOverdue() timezone bug (ISO string compare)
- useAssist.ts: accept() now resets state to idle when document changed since proposal
- stores/chat.ts: fix memory leak in _pollUntilLoaded() (try/catch around fetchStatus)
- TiptapEditor.vue: selection offset uses closest-match strategy (not first-match)
- utils/markdown.ts: explicit DOMPurify config with FORCE_BODY; remove as const
(DOMPurify expects mutable string[])
New features:
- Auto-save (5-minute interval) in NoteEditorView and TaskEditorView — only when
editing an existing dirty record; silent on error, shows "Auto-saved" toast
- sectionParser.ts: top-level bullet/numbered list items are now individual sections
in the AI Assist panel (previously treated as one undifferentiated block)
- editor-shared.css: extracted ~500 lines of CSS duplicated between both editors;
includes .inline-assist-btn at global scope (required for teleported elements)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add GET /api/chat/ps and POST /api/chat/warm endpoints for hot model
visibility and pre-loading
- Extend PATCH /api/chat/conversations/:id to accept model in addition
to title
- Add ModelSelector component with hot/cold indicators from Ollama /api/ps
- Add DashboardChatInput component (model selector + note picker + textarea)
replacing the simple "New Chat" button on the dashboard
- Add model selector dropdown to ChatView header, persisted per-conversation
- Warm default model on dashboard mount via fire-and-forget background task
- Configure Ollama with OLLAMA_MAX_LOADED_MODELS=2 and OLLAMA_KEEP_ALIVE=30m
- Always-visible edit buttons on NoteCard/TaskCard (remove hover-only behavior)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dashboard improvements:
- Added "Due This Week" section (next 7 days) and "High Priority" section
(amber accent, catches high-priority tasks not already shown by date)
- All task sections sort by priority desc then due date asc
- Cascading deduplication via shared seen-set across all 5 sections
- Combined due-today + due-this-week into single API call, split client-side
- Removed unused `tomorrow` variable (fixed vue-tsc build error)
Inline edit buttons:
- NoteCard and TaskCard show "Edit" button on hover (always visible on touch)
- Navigates directly to edit view via .prevent.stop on router-link cards
- Styled as subtle bordered button, highlights to primary on hover
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Improve chat context: build_context() now returns metadata about auto-found
notes, emitted as an SSE event so the frontend can display context pills
showing which notes influenced the response. Users can promote notes for
deeper context (+) or exclude irrelevant ones (x). A note picker lets users
manually attach notes. Multi-word search uses per-term AND matching, and
auto-search iterates keywords individually for broader OR-style coverage.
Standardize styling: introduce CSS design tokens (--radius-sm/md/lg/pill,
--color-success/warning/overlay, --focus-ring) and migrate all components
to use them. Fix header alignment to full-width, add active nav link state,
replace hardcoded colors with CSS variables, and normalize button padding.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>