Add 8 system pages as first-class workbench apps (Settings, Themes,
Profile, Admin, API Keys, Help, Feedback, Subscription) so they can be
opened as side-by-side panels next to other apps instead of requiring
a full-page route switch. Existing routes remain as fullscreen
fallback/deep-link targets.
Group the AppPagePicker by 5 categories (Companion, Leben, Arbeit,
Kreativ, System) with collapsible sections; System is collapsed by
default. Search still works as a flat fuzzy match across all apps.
Category assignment lives in a central map so registerApp() calls stay
unchanged — unmapped apps fall back to System, which surfaces
miscategorization at a glance.
Remove profile-data and theme-picker duplication from Settings (both
are separate workbench apps now): Settings defaults to 'Allgemein' and
passes showTheme={false} to GlobalSettingsSection; SettingsSidebar
accepts a categories override so the workbench version hides Profile.
Fix Cannot-read-'subscribe'-of-undefined crash in mood/sleep/body/
stretch ListViews when opened in the workbench: replace getContext
(which is only set by the route +layout.svelte) with direct query-hook
calls, matching the goals/companion pattern.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Five fixes from observed chat where user asked to complete two
tasks by title but the LLM had no way to find their IDs:
1. Tool result history: messagesToLlm() now includes previous
tool_result messages as "[Previous tool result]" entries so
the LLM can reference IDs/data from earlier turns.
2. Bare JSON tool call fallback: extractToolCall() now also
matches bare {"name":..., "params":...} JSON without the
```tool fence — the LLM kept dropping the fence.
3. IDs in list message: list_tasks now formats each entry as
"• [abc123] Title" so the LLM has the ID alongside the title.
4. New complete_tasks_by_title tool: case-insensitive substring
match, completes all matches at once. Handles "erledige beide
sicher sicher tasks" without needing IDs.
5. System prompt updates: explains the [id] bracket convention,
warns the LLM to NEVER show raw IDs to users, and references
the new tool for title-based completion.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two fixes for the chat where the user asked "show my tasks" and the
LLM responded with "I don't have direct access to a dynamic task list":
1. New list_tasks tool with title/dueDate/priority for each task,
filterable by open/completed/overdue/today/all (default: open).
The message field returns a markdown bullet list so the LLM can
pass it through directly.
2. System prompt rewritten to explicitly tell the LLM:
- WHEN to call which tool (concrete examples for common questions)
- "Erfinde keine Daten" — don't make up info, call a tool
- Tool format must be JUST the JSON block, no preamble
Common questions now have explicit mappings:
- "Welche Tasks?" → list_tasks
- "Wie viel Wasser?" → get_drink_progress
- "Welche Termine heute?" → get_todays_events
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three UX fixes for the Companion Chat:
1. Markdown rendering: assistant messages now render as HTML via
marked (gfm + breaks). **bold**, _italic_, lists, code blocks,
links all work. Custom CSS for Mana theme integration.
2. Loading status: while the local Gemma model downloads/loads
(first use is ~500MB), the placeholder bubble shows "Modell
wird geladen... 42%" with a spinning icon instead of just a
blank "thinking" state.
3. Streaming feedback: the placeholder bubble appears immediately
when sending and shows tokens as they stream from the LLM,
rendered as markdown in real-time. Auto-scrolls on each chunk.
The pulse animation on the streaming markdown gives a subtle
"this is generating" hint.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Final two TODOs resolved — the Companion Brain backlog is now empty.
Goal Editor (GoalEditor.svelte):
- Modal with event type picker (13 options), count/sum mode,
optional filter field/value, target value/period/comparison
- Integrated into Goals ListView with "Eigenes" button alongside
the existing "Vorlage" template picker
- Creates custom goals via goalStore.create()
Incremental Streaks (rewritten streaks.ts):
- Persistent _streakState table replaces the 90-day lookback scan
- 6 streak definitions: water goal, tasks, meals, workout, journal,
meditation — each triggered by specific domain events
- Event bus subscription marks streaks active on matching events
- markActive() is O(1): read state → check if today already active
→ increment or reset based on consecutive day check
- useStreaks() reads from _streakState (single table scan, no
per-day queries) instead of 270+ queries worst case
- startStreakTracker/stopStreakTracker wired into layout lifecycle
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three remaining TODOs resolved:
1. NudgeToast (in-app nudge display):
- New NudgeToast.svelte in bottom-stack alongside SuggestionToast
- Evaluates Pulse Rules every 60s, shows nudges as toasts
- Action button navigates to module route, dismiss records outcome
- Badge shows count when multiple nudges are queued
2. Server LLM fallback:
- Companion engine now tries local LLM (Gemma/WebGPU) first
- Falls back to mana-api /api/v1/chat/completions if no WebGPU
- isCompanionAvailable() returns true if either path works
- Graceful error messages when neither is available
3. Trigger-Event bridge (legacy automation migration):
- event-bridge.ts maps 13 domain event types to legacy
(appId, collection, op) format
- Existing user automations now fire on domain events too
- Domain events carry decrypted data → condition matching on
encrypted fields (title, etc.) works correctly
- Bridge wired into layout startup/cleanup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Final optimization pass for the Companion Brain.
New modules (31 total):
- Meditate: MeditationCompleted event + log_meditation tool
- Sleep: SleepLogged event + log_sleep tool
Performance: DaySnapshot buildSnapshot() now runs all 6 Dexie
queries + 4 decryption passes in parallel via Promise.all instead
of sequentially. Estimated 3-5x speedup on first render.
Cleanup: trackActivity() in database.ts is now a no-op — the
_activity table is no longer written to. getRecentActivity() in
activity.ts delegates to queryEvents() from the Domain Event Store,
converting domain events to the legacy ActivityEntry shape.
Totals: 69 event types, 49 tools across 31 modules.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Registers Mein Tag, Event Stream, Companion Chat, and Ziele as
workbench apps so they can be added to scenes alongside existing
modules like Todo, Calendar, etc.
New workbench pages:
- Mein Tag (myday): DaySnapshot overview — tasks, events, water
progress, nutrition, streaks at a glance
- Events (eventstream): live domain event feed with icons, labels,
and timestamps — shows the system "pulse" in real-time
- Companion (companion): embedded chat interface that auto-creates
a conversation on first use
- Ziele (goals): goal cards with progress bars, template picker
for quick goal creation, pause/resume/delete
Each page registered in both app-registry (workbench views) and
shared-branding (app metadata, icons, descriptions, tier=guest).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Bump companion tables to db.version(14) so the schema upgrade
runs even on browsers that already saw v10 with only _events
- Add try/catch to useConversations() and useMessages() queries
to prevent silent crashes if tables don't exist yet
- Use db.table() directly in chat store instead of collections.ts
module-level references (avoids eager table resolution issues)
- Add min-height to empty state and companion page container
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Phase 5 of the Companion Brain. Introduces the Companion Chat that
ties together all previous phases into a conversational interface.
Module (modules/companion/):
- types.ts: LocalConversation + LocalMessage with tool call/result fields
- collections.ts: companionConversations + companionMessages tables
- stores/chat.svelte.ts: conversation + message CRUD
- queries.ts: reactive useConversations() + useMessages()
- engine.ts: chat orchestration — builds system prompt from Context
Document, sends to local LLM (Gemma via @mana/local-llm), handles
tool calls via JSON extraction + executeTool(), supports multi-round
tool calling (max 3 rounds)
UI:
- CompanionChat.svelte: message list, streaming output, tool result
display, keyboard submit (Enter)
- /companion route: sidebar with conversation list + chat area
Also updates the architecture plan with Phase 1-4 completion status.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend: Hono/Bun service on port 3042 with JMAP client for Stalwart,
account provisioning (@mana.how addresses on user registration),
thread/message/send/label API endpoints, and JWT + service-key auth.
Frontend: Mail module with 3-column inbox UI (mailboxes, thread list,
detail/compose), local-first encrypted drafts in Dexie, and API-driven
thread fetching. Scoped CSS with theme tokens.
Integration: Dexie v11 schema, mail pgSchema in mana_platform,
mana-auth fire-and-forget hook for account provisioning,
getManaMailUrl() in API config, app registry + branding update.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Phase 2 of the Companion Brain. Adds live-reactive projections that
aggregate data across all 5 pilot modules into high-level views:
- DaySnapshot: today's tasks (total/completed/overdue/due), calendar
events (upcoming/next), drink intake (water/coffee/total with goals),
nutrition (meals/calories/protein with goals), places visited
- Streaks: consecutive-day tracking for water goal, task completion,
and meal logging with active/at_risk/broken status (90-day lookback)
- Context Document: ~500 token markdown generator combining DaySnapshot
+ Streaks for LLM system prompts
Also wires startEventStore() into the app layout so domain events
from Phase 1 are persisted to IndexedDB on every module mutation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New "Dehnen/Stretch" module for guided stretching with timer-based sessions,
mobility self-assessments, streak tracking, and configurable reminders.
Includes: 22 seed exercises, 5 preset routines (morning, desk break, evening,
upper body, lower body), fullscreen session player with Performance.now() timer
and Wake Lock, 6-step mobility assessment wizard with scoring, 30-day heatmap,
body region balance chart, custom routine builder, and reminder management.
Registered in module-registry, encryption registry (5 tables), database v9,
seed-registry, app-icons, mana-apps, and workbench app-registry.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Phase 1 of the Companion Brain architecture. Introduces a typed,
synchronous event bus with microtask-scheduled handlers, an append-only
event store persisted to IndexedDB (_events table, v10 schema), and
semantic domain events emitted from module stores.
Pilot modules with emit() calls:
- Todo: TaskCreated, TaskCompleted, TaskUncompleted, TaskDeleted, SubtasksUpdated
- Calendar: CalendarEventCreated, CalendarEventUpdated, CalendarEventDeleted
- Drink: DrinkLogged, DrinkEntryDeleted, DrinkEntryUndone
- Nutriphi: MealLogged, MealFromPhotoLogged, MealDeleted
- Places: PlaceCreated, PlaceDeleted, PlaceVisited, LocationLogged,
TrackingStarted, TrackingStopped
Also includes the full architecture plan at
docs/architecture/COMPANION_BRAIN_ARCHITECTURE.md.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New "Rezepte" module following the established scoped-CSS + theme-token
pattern. Includes Dexie schema (v8), encryption for user-typed fields,
3 German seed recipes, search/filter/tag UI, inline creation form, and
expanded detail view with ingredients checklist and numbered steps.
Also documents the frontend styling inconsistency (13/40 ListViews use
Tailwind instead of scoped CSS) in docs/optimizable/ for future cleanup.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- PageShell maximized: fill viewport edge-to-edge (max-width none, z-index 95
above bottom bar, border none), constrain body/header to 48rem centered, Esc
exits fullscreen
- SceneAppBar: pill-shaped bar and items, match TagStrip font size (0.9375rem),
visual group bracket for active scene with separator, tab count on all scenes,
inline name input for new scenes instead of modal dialog
- SceneRenameDialog: remove icon field, simplify to name-only
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces specific tool names (Todoist, Notion, ChatGPT, etc.) with
generic categories (Aufgaben-App, KI-Assistent, etc.) in the
comparison section.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Removes all star ratings from the features page. Replaces the card
grid summary with a flowing paragraph of clickable keyword links
that scroll to each feature section. Both simple and tech views
updated.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rewrites all USP texts for non-technical users (no jargon like
IndexedDB, tables, AES-GCM-256). Adds a "Für alle / Technik" toggle
switch that swaps between user-friendly marketing copy and deep
technical architecture details. Toggle state persists in localStorage.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds a comprehensive features page listing all 12 USPs of the Mana
platform with usefulness ratings (3-5 stars), detail bullet points,
and a cost comparison section (Mana vs individual tools). Also fixes
a devlog content schema error (category 'fix' -> 'bugfix') and adds
a footer link to the new page.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
getAccessToken() reads the stored JWT without checking expiry, causing
401s when the token ages out — especially for services not covered by
the fetch interceptor (credits, events, api, etc.). getValidToken()
checks validity first and refreshes automatically when needed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The workbench ListView was using Function() (effectively eval) with
aggressive sanitizing that stripped valid characters, causing every
calculation to fail with a generic "Fehler". Now uses the same safe
parser as the standard calculator page. Also adds console.error
logging and shows result before persisting to DB.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Clicking a mood now opens it immediately in fullscreen (browser
Fullscreen API, z-index above all UI). Preview step removed.
Cards redesigned with full gradient backgrounds, live animations,
gradient overlays, and hover border highlight.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New module for tracking all beverages (water, coffee, tea, juice, alcohol, etc.)
with daily progress bar, quick-tap presets, and inline editing of quantity/date/time.
Includes: module config, types, collections with guest seed (5 presets),
queries, store, ListView with context menus, route, app-registry registration,
Dexie schema v7, encryption registry, shared-branding icon/app entry.
Also extends docs/future/MODULE_IDEAS.md with additional module ideas.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Docker build failed because @mana/local-stt was added as a
workspace dependency but not COPYed into the build context.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
transcribeAudio() now checks localSTT.isReady before falling back to
the server-side mana-stt proxy. When local STT is active, audio blobs
are decoded to Float32Array via AudioContext.decodeAudioData() and
transcribed entirely on-device. The returned model field shows
"Whisper Tiny (lokal)" or similar so every module (dreams, memoro,
habits) displays which backend was used — no module code changed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract the floating pill-shaped input bar (text + optional voice)
into a shared component at $lib/components/FloatingInputBar.svelte.
Migrate todo, calendar, dreams, notes, journal, memoro and contacts
from inline forms / VoiceCaptureBar to the unified bottom bar.
Calendar now shows all upcoming events with relative date labels
(Heute, Morgen, weekday name, or short date).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Stripped stats counters, filter tabs, and VoiceCaptureBar. Now shows
a flat list with round monochrome checkboxes, inline due-date badges
(Überfällig/Heute/date), completed tasks below a divider with
completion timestamp, and a pill-shaped FloatingInputBar at the
bottom with integrated voice input.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PageShell header icon/title had opacity: 0.5 — removed for full
visibility. Moodlit, Zitare, Skilltree and BaseListView used
text-white/* classes that were invisible in light mode — migrated
to hsl(var(--color-foreground/muted-foreground)) tokens.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PillNav overhaul:
- Dropdown-as-bar: theme/AI/sync/user menus render as horizontal
bars in the bottom stack (PillDropdownBar) instead of floating
popovers. New onOpenBar/activeBarId props on PillNavigation.
- iconOnly pills: tags/search/workbench-tabs pills show only icons.
Home pill removed. New iconOnly flag on PillNavItem.
- Segmented toggle groups: items sharing a `group` id render as a
single segmented pill (e.g. Light/Dark/System triple).
- Fullscreen mode: press "f" to hide all bottom chrome, Esc to exit.
- QuickInputBar + bottom bar visibility toggles via new pills.
- Progress ring on AI trigger pill during model download
(conic-gradient ::after, follows pill border-radius).
@mana/local-stt — new package for browser-local speech-to-text:
- Whisper models via transformers.js v4 (WebGPU + WASM fallback)
- Same Web Worker architecture as @mana/local-llm
- Two models: Whisper Tiny (150 MB) and Whisper Small (950 MB)
- Reactive Svelte 5 bindings (getLocalSttStatus, loadLocalStt, transcribe)
Voice-to-text integration:
- useLocalStt() composable: mic capture via AudioContext +
ScriptProcessor, resample to 16kHz mono, feed into Whisper worker
- Mic button in QuickInputBar (leftAction slot) with
recording/loading/transcribing states + pulse animation
- Transcribed text injected into InputBar via new injectedText prop
- STT model selector in AI bar alongside LLM tier controls
Also: vite.config.ts server.fs.allow expanded to monorepo root
so workspace package workers resolve in dev.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wallpaper system with four sources (predefined images, CSS gradients,
custom uploads via mana-media, and theme default). Configurable per-scene
or globally, with overlay controls (blur + opacity) and hover preview.
Adds sticky prop to shared PageHeader component and applies it across
themes, settings, credits, subscription, help, and profile pages.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The presi module's schema was defined inline in routes.ts but had no
working db:push mechanism — the old references to @presi/server and
@presi/backend no longer exist after consolidation. Extracts schema
into its own file, adds a dedicated drizzle config, and updates the
setup script so tables are actually created.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PageShell cards now fill the available viewport between the workbench
top padding and the bottom chrome instead of using a static 60vh.
Height is calculated via two CSS vars published by the layout <main>:
height: calc(100dvh - var(--bottom-chrome-height) - var(--workbench-reserved-y))
--bottom-chrome-height reacts to pill-nav collapse, tag strip toggle
and bottom-bar mount state. --workbench-reserved-y (2.5rem) folds the
wrapper padding + buffer into a single non-chrome offset. dvh handles
Safari's retractable address bar. Inline height from resize-drag still
overrides as before.
Bottom-stack bars now use a uniform `gap: 0.25rem` instead of ad-hoc
per-child padding-bottom, giving consistent 4px spacing between all
bars. Wrapper vertical padding reduced from py-4/py-8 to py-2/py-3
and main's bottom buffer from +32px to +8px — cards gain ~72px of
usable vertical space on a typical viewport.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Switch PageShell's per-theme paper overlay from a ::before +
mix-blend-mode + opacity stack to direct background-blend-mode on the
element itself. The old approach had invisibility issues in dark mode
and stacking-context quirks that made the grain disappear entirely.
background-blend-mode against background-color is the simpler, more
reliable primitive.
utils.ts auto-switches multiply → overlay in dark mode (dark × dark is
essentially invisible) while leaving other blend modes as-is. The
opacityLight/opacityDark knobs are gone from the paper config since
background-blend-mode has no opacity slot — tune via blendMode choice
instead.
Visual tuning pass:
- Card border bumped from 1px box-shadow ring to a real 2px border
with background-clip: border-box so the paper texture reads
continuously across the edge. Alpha 0.12 light / 0.28 dark (black).
- Drop shadow deepened (0 8px 24px + 0 3px 8px) for more card lift.
- Stone theme cooled toward real slate-blue: hue 200 → 212, saturation
bumped ~10pts across the palette. Stone was reading as warm-neutral
grey, now it's a proper cold blue.
- Texture remap: Lume → paper-004 (strongest grain, 480px tile for
coarser fiber), Stone → cardboard-002 (linen), Lavender → paper-001
(freed up after Stone claimed cardboard-002).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>