Commit Graph
128 Commits
Author SHA1 Message Date
sandrodachandClaude Opus 5.5 4a923eaf01 feat(pwa): loading screen in the colours of the last used theme
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 10:12:55 +01:00
sandrodachandClaude Opus 5.5 25bb787a8e feat(lists): drag tasks and list entries onto another list; remember open list and view; live pill in lists
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m3s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 10:01:41 +01:00
sandrodachandClaude Opus 5.5 6a855fc32c feat(workspace): slash commands ranked by name, taller link cards with a link marker
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m22s
- /li lists /link first: name prefix, aliases, name, then description
- link cards about twice as tall; the bare address below becomes an accent
  link marker; the link chip bar under bullets is gone, bare web addresses
  in text are links themselves

chore(release): v0.14.3

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 00:19:19 +01:00
sandrodachandClaude Opus 5.5 3f0e596356 feat(themes): colour families with light/dark, follow system, corners, frames, accent
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m30s
- Fjord (new), Polarized Hell and Suri Hell complete the families
  Klassik, Fjord, Terrakotta, Polarized, Suri
- settings: family table, follow-system, corners, button frames and an own
  accent colour (per device); compact quick picker in the user menus
- code colours in index.css are fallbacks only

chore(release): v0.14.0

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 23:29:52 +01:00
sandrodachandClaude Opus 5.5 2c9b4762fc feat(ui): Terrakotta Nacht replaces Soft, smooth menus and sliding notes on phones
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m21s
- dark counterpart of Terrakotta; Soft users move to it
- add tailwindcss-animate: the existing animate-in/fade/slide classes now
  run; menus zoom in, sheets slide up, notes slide in on phones
- no animations with reduced motion

chore(release): v0.13.0

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 23:12:05 +01:00
sandrodachandClaude Opus 5.5 acd18abe8a feat(themes): Terrakotta replaces High Contrast; equal header buttons on phones
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m20s
chore(release): v0.12.0

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:53:03 +01:00
sandrodachandClaude Opus 5.5 2f0369f7a2 style: lighter inline code, black system bars for the installed app
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:30:04 +01:00
sandrodachandClaude Opus 5.5 e243e328c7 fix(markdown): formatting inside bold/italic/strike, monochrome inline code
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m17s
Bold, italic and strikethrough render their inside again, so **`code`**
shows bold code instead of backticks; inline code uses the theme's code
background with the main text colour instead of the accent colour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:13:55 +01:00
sandrodachandClaude Opus 5.5 b136e5dfad feat(workspace): sliding sidebar in focus mode, calmer workspace bar, smoother journal
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m47s
- focus mode: folders slide in from the left (button, title click, or the
  left edge on wide screens); picking a note keeps focus mode
- workspace bar: borderless live/shared/save pills in one style, divider
  before the note actions; footer without top line
- journal panel and calendar open with an animation, the view fades in
- paste and markdown import nest a list under the paragraph introducing it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:04:30 +01:00
sandrodachandClaude Opus 5.5 141f87f3a0 Merge branch 'feat/footer-share-ci' into dev
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m39s
CI keeps the 'test once per code state' plan but records commit and
git tree as image labels instead of extra :sha-/:tree- tags, so the
registry only holds dev, latest, vX.Y.Z and stable; the plan test now
asserts the expected decisions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 21:29:56 +01:00
sandrodachandClaude Opus 5.5 38b8c92899 feat(notify): web push as a notification channel
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m15s
- VAPID keys from VAPID_* or generated once (push_keys, migration 9);
  devices in push_subscriptions, forgotten on 404/410 from the push service
- push column for every event (also due tasks) and the daily summary,
  bundles as one notification; /push/key, /devices, /subscribe,
  /unsubscribe, /test
- settings: switch push on per device, test it, see the devices; the
  service worker shows notifications and focuses MindSift on click
- tests decrypt a sent push like a browser (RFC 8291) and check VAPID

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 21:21:55 +01:00
sandrodachandClaude Opus 5.5 1a49e6b304 feat(workspace): links to single bullets
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m8s
- copy a link to a bullet from its action bubble or pick a bullet in the
  link dialog; [[Note#^id|Note › excerpt]] opens the note, jumps to and
  highlights the bullet, or says it is gone
- wiki links render inline with their label and are clickable; the
  duplicate chip below the text is gone

test(e2e): run each suite with its own container, image tag and port, so
parallel runs from another working copy no longer remove our server

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 20:42:14 +01:00
sandrodach 86d2cd0138 feat(pwa): add web share target for text and images with offline queue 2026-10-30 20:23:54 +01:00
sandrodach c181ffea54 feat(ui): add desktop footer, legal custom link and about dialog 2026-10-30 20:19:02 +01:00
sandrodachandClaude Opus 5.5 375dda982b feat(workspace): journal panel toggle, view kept across tabs, sections nest under headings
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m9s
- the journal opens as a framed panel and closes on a second click,
  returning to the previous note; journal state and the last regular note
  survive tab switches, the fallback note is never a journal day
- pasted and imported markdown nests content under its heading (H2 below
  H1), Enter on a heading creates a child, '- ' / '* ' / '+ ' start a bullet

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 20:11:09 +01:00
sandrodachandClaude Opus 5.5 2bfe74e66b feat(workspace): numbered lists and reliable markdown paste
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m5s
- block type 'numbered' (/number): 1., a., i. by nesting, continues on
  Enter, an empty item ends the list; markdown export/import as 1.
- pasting: parser moved to lib/pasteOutline with tests; blank lines split
  paragraphs, numbered lists keep their type, indentation levels follow
  the widths in use (2, 3 or 4 spaces, tabs)
- text that stays in the focused block after pasting (a paragraph with
  line breaks) was dropped; the block now takes it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 19:36:15 +01:00
sandrodachandClaude Opus 5.5 9008d7c915 feat(workspace): journal with one note per day and a calendar
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m6s
- journal_days (migration 8) maps a person's day to an ordinary note;
  GET /journal lists the days, POST /journal/{date} opens or creates one
- the journal sits on top of the notes sidebar: days below each other
  (today first, older ones load while scrolling), a calendar with month
  and year picker follows the day in view and jumps to any day
- the header shares the day in view; journal notes stay out of the folder
  tree; can be switched off per device under Darstellung

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 19:20:58 +01:00
sandrodachandClaude Opus 5.5 261579f0f2 feat(notify): own webhook as a full notification channel
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m59s
The custom webhook could be entered but never switched on since the
notification matrix replaced the old alarm channels. It is now a third
column next to e-mail and Discord for every event and the daily summary;
bundles go out as JSON (event "digest").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 19:02:46 +01:00
sandrodach a317ce0fee feat(workspace): add formatting shortcuts for bold, italic, and links in outliner 2026-10-30 16:22:55 +01:00
sandrodach fc7b2b3a2c Merge remote-tracking branch 'origin/dev' into feat/gemini-workspace
# Conflicts:
#	CHANGELOG.md
2026-10-30 09:33:23 +01:00
sandrodach d2afcf49df feat(notifications): add channel routing matrix, daily summary, and task watch button 2026-10-30 09:32:52 +01:00
sandrodach 6795edbf4b feat(voice): live dictation with browser pause restart and server audio chunking 2026-10-30 09:27:30 +01:00
sandrodach 446f8e4649 fix(workspace): tighten link preview card, slash menu matching/scrolling, and Enter on last empty bullet 2026-10-30 09:21:29 +01:00
sandrodachandClaude Opus 5.5 362dd3b4c6 fix(workspace): extract replaces the branch in the editor, with undo
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m2s
The server only creates the new note and returns the link; the editor
swaps the branch for it as an ordinary own edit through the sync engine.
No more clash with unsent typing (conflict copies), the link shows at
once also with polling, and Strg+Z restores the branch. Undoing (toast or
Strg+Z) puts the new note into the trash via POST /extract/undo. The
sidebar gets the new note right away and opens its folder.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 09:18:25 +01:00
sandrodachandClaude Opus 5.5 4d1b37c956 feat(workspace): turn a branch into its own note, merge notes
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m56s
- Extract: button on the bullet (desktop) or /extract (/notiz). The bullet
  becomes the title (hashtags stay at the link), its children the content
  of a new note in the same folder with the source's shares (a foreign
  source owner gets write access); the branch becomes [[title]] through
  the operation log, so open editors follow.
- Merge: drop a note onto another in the sidebar or use "Mit anderer
  Notiz zusammenführen…" in the note header. The own source is appended
  as an h2 section with its bullets below and goes to the trash; the toast
  offers a complete undo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 00:25:46 +01:00
sandrodachandClaude Opus 5.5 4c26eb2960 feat(workspace): link previews above bullets with a web address (M5)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m52s
- GET /link-preview?url= fetches the page on the server (https only,
  SSRF-guarded like webhooks), reads Open Graph/Twitter tags, title,
  description and icon from the head, loads picture and icon (no SVG) and
  keeps them in link_previews (migration 6) for 7 days; readers' browsers
  never contact the page. Off in the demo; 300 fetches per address in
  15 minutes.
- Compact card above the bullet (icon, site, title, one line, small
  picture); the duplicate link badge is left out.
- ✕ turns the address into [title](url), so hiding syncs with the note;
  "Link-Vorschauen anzeigen" under appearance switches all off per device.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 00:06:05 +01:00
sandrodachandClaude Opus 5.5 56c1fa02e6 feat(mail): sender display name (SMTP_FROM_NAME, default MindSift)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m54s
A bare SMTP_FROM address gets the display name in the From header; a name
already in SMTP_FROM wins, the envelope keeps the bare address. Also a
field in the admin mail settings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 23:47:38 +01:00
sandrodachandClaude Opus 5.5 3f5e3b2ac1 feat(workspace): voice notes via /audio (M3)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m10s
- /audio (only in an empty bullet) shows a recording bubble: green round
  button starts, it turns red with a live wave and timer on its left, a
  tap saves the recording as an inline audio player. An audio file can be
  uploaded instead; Esc/✕ restores the empty bullet.
- Chrome's WebM recordings get their length measured, so the player shows
  the total time and seeking works.
- With the own Whisper server "Transkribieren" turns the recording into
  the (searchable) caption.
- Loaded files keep their Blob, as the CSP rightly blocks fetch() on blob:
  URLs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 23:23:54 +01:00
sandrodachandClaude Opus 5.5 e8fa14a4cb feat(workspace): image blocks via /bild (M2)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m18s
- /bild (only in an empty bullet) turns the bullet into an inline picker:
  file, camera on phones, drag & drop, paste, or an https link the server
  copies. Esc/✕ restores the empty bullet; nothing is synced before the
  upload succeeded.
- Photos are shrunk to 2048 px and stored as WebP (JPEG fallback); the
  re-encoding drops EXIF data such as the location.
- Image block: loaded with the login as blob URL, click opens full
  screen, optional caption kept in the block content
  (![caption](media:id)).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 23:14:08 +01:00
sandrodachandClaude Opus 5.5 7fa21e485b feat(voice): all microphone buttons use the server's speech recognition
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m56s
- New useVoiceInput hook (lib/voice.ts): "server" records with MediaRecorder
  and sends to /voice/transcribe, "browser" keeps the live recognition,
  "off" or missing browser support hides the microphone.
- Quick dump bar, mobile capture sheet and hold-to-record use it; live
  waves from the real input level (VoiceWave) and "Wird erkannt…".
- Recordings stop after STT_MAX_SECONDS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:23:48 +01:00
sandrodachandClaude Opus 5.5 7801cd13b9 feat(voice): self-hosted speech recognition via Whisper (STT_*)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m49s
- STT_URL switches voice input to an OpenAI-compatible Whisper server
  (e.g. speaches); without it the browser's recognition stays. Configured
  by environment only, with limits for upload size, parallel jobs, hourly
  budget per user and timeout. The demo always uses the browser.
- POST /voice/transcribe forwards recordings and returns the text; nothing
  is stored. On startup MindSift waits for the server and asks it to
  download the model if missing.
- Admin card shows the active mode and server state, with a test recording.
- docker-compose: optional "whisper" service (speaches 0.8.3 CPU, profile
  "whisper", models in ./whisper).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:12:57 +01:00
sandrodachandClaude Opus 5.5 fbc404fea1 fix(notes): no self-conflicts when typing in a rhythm
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m51s
Several unsent text changes of one block were applied one by one to the
local view, numbering local versions ahead of the server, which folds them
into one change (formBatch). The focused field kept the inflated version as
base, so the next edit after a sync conflicted with the user's own text.
The local view now applies pending ops as they will be sent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 21:13:02 +01:00
sandrodachandClaude Opus 5.5 9d9698186c fix(security): demo sends nothing, hidden SMTP password, body limits (FLAW-33..38)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m52s
- Demo: senders for mail, Discord and webhooks refuse, no alarm ticker;
  test alarm, SMTP test, server settings, backups, account and session
  changes of the shared demo accounts answer 403; the session list only
  shows the own device. The UI shows the notices and disables the controls.
- SMTP password is never sent back (smtpPassSet), empty keeps it.
- ?token= on webhook ingest accepts only API keys.
- Request bodies capped at 2 MB (sync 8 MB, imports 101 MB).
- Deleting an account removes its server backups.
- Backup downloads, exports and import uploads get 30 minutes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 19:43:23 +01:00
sandrodachandClaude Opus 5.5 1af3a6e90a feat(auth): server-side sessions and current password for account changes (FLAW-30, FLAW-31)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m52s
- Every login is a session (device, IP, last use); the token's jti is its ID.
  Sessions end on logout, per device from the profile, or after 30 idle days.
- Tokens older than a day are renewed via the X-Session-Token header.
- Changing password or login e-mail needs the current password; a new
  password logs out all other devices and mails the old address.
- Demo reset keeps the demo visitors' sessions.
- revoked_tokens is replaced by sessions (migration 4); everyone is logged
  out once after the upgrade.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 19:25:22 +01:00
sandrodachandClaude Opus 5.5 b2ecda9896 fix(security): safe links and security headers (FLAW-28, FLAW-29)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m48s
safeHref lets only http, https and mailto become links (Markdown viewer,
outliner, legal links); javascript: and friends show as text. A
middleware sets a Content-Security-Policy (scripts only from MindSift,
no framing, connections only to this server), X-Frame-Options,
nosniff, Referrer-Policy and a Permissions-Policy. The two inline
scripts of index.html moved to files so script-src stays 'self'.

The second inline script also deleted every cache on each page load,
which undermined the offline start; it is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 19:02:13 +01:00
sandrodachandClaude Opus 5.5 64e077dd57 feat(backup): admin and account UI for server backups, import by section
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m44s
Admin settings: switch, time, retention, list with download and a
"Jetzt sichern" button. Account settings: own server backups with
download and restore (replace or add, for chosen sections, replace needs
a second tap). The MindSift import gets the same section picker.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 16:11:49 +01:00
sandrodachandClaude Opus 5.5 0fdf46635b test(frontend): task dialog, sharing avatars, trash, API key scopes, passwords (FLAW-19)
Covers opening and closing the task dialog (the former hook-order bug),
date/time fields and the view-only mode for viewer lists, the avatar
stack of shared items, the two-tap delete in the trash, scope selection
and badges of API keys, and the shared password rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 15:03:54 +01:00
sandrodachandClaude Opus 5.5 4c50d15915 chore(frontend): real ESLint instead of a placeholder; fix hook order (FLAW-19)
eslint.config.js with the recommended JS/TypeScript rules and the React
hooks rules; npm run lint runs ESLint and is part of the image build.
Errors fail the build, the 24 exhaustive-deps findings stay warnings.

It found two real bugs: TaskDetailModal and ManageColumnsModal called
their hooks after 'if (!isOpen) return null', so the hook count changed
whenever the dialog opened or closed. Both are now a thin wrapper plus a
content component. Also removes unused imports and dead code (old task
list share handlers, an unused realtime status, an unused rollup).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 15:02:52 +01:00
sandrodachandClaude Opus 5.5 f57a9884d1 fix(security): stream tickets instead of session tokens in URLs (FLAW-22)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m32s
WebSocket and EventSource put the 30-day session token into the URL,
where proxies log it. The app now gets a one-time ticket right before
connecting (POST /auth/stream-ticket, 60 s, bound to the token version);
?token= is no longer accepted for streams, non-browser clients may use
the Authorization header.

With BASE_URL set, CORS allows only that origin and WebSocket upgrades
only it or the requested host; credentials are off (no cookies exist).
Logout, ending all sessions, a new password and deactivation close all
live streams of the account; clients with a valid session reconnect
with a fresh ticket.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 14:46:58 +01:00
sandrodachandClaude Opus 5.5 5c711c2cf7 feat(api-keys): scopes for triage, tasks and list items (FLAW-07)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m33s
Keys get scopes when created (webhook:triage, webhook:task,
webhook:list; default triage, old keys become triage). The webhook
ingest learns target task (optional task list) and list_item (needs a
list the owner may write to); /inbox checks the scope of its target as
well; a missing scope answers 403. Keys can no longer open live streams,
which carried all of the owner's events.

The visible key UI lived in the account settings while EcosystemView
was never rendered; it is replaced by ApiKeysPanel in the settings with
scope chips, scope badges per key and a simulator for all three
targets. Examples send the key as X-API-Key header, not in the URL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 14:36:17 +01:00
sandrodachandClaude Opus 5.5 6b9eb62caf feat(demo): reset the demo instance every 20 minutes with a countdown
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m34s
DEMO_RESET_MINUTES (default 20, 0 = off) resets the database to the
sample data. Demo accounts get fixed IDs so sessions survive; requests
hold a read lock so the reset never runs under a half-finished request
(streams excluded). DEMO_RESET goes to every connection, /auth/status
announces the next reset. The app shows "✨ Demo · Reset in MM:SS" in
place of the version, then clears cached answers, remounts the views,
reloads in the background and shows a short notice; if no event
arrives (long polling) it asks the server after the countdown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 14:22:06 +01:00
sandrodachandClaude Opus 5.5 c4fc455850 feat(ui): open list items counter on Listen, none on Workspace
New stat listItemsOpenCount: unchecked items in all lists the user sees
(own, shared directly or through a group), shown as accent counter on
Listen in the header and the mobile bottom bar. Workspace loses its
counter. Stats refresh on list events and after deleting an item.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 12:43:56 +01:00
sandrodachandClaude Opus 5.5 b5f926bcf7 fix(auth): new passwords need at least 8 characters (FLAW-09)
auth.ValidatePassword checks every way a password is set: setup,
registration, profile, admin create and reset, reset by mail. Same rule
in the browser before sending (lib/password.ts), with our own German
message instead of the browser popup. Existing shorter passwords still
log in. Profile and admin reset no longer trim the password, which made
passwords with surrounding spaces unusable for login.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 12:20:46 +01:00
sandrodachandClaude Opus 5.5 ee60a03e8c Merge branch 'theme/polarized-teal' into dev: Polarized in green/teal
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m36s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 11:04:31 +01:00
sandrodach 51a41df14b feat(theme): revise Polarized to classic green/teal dark palette 2026-10-29 09:15:20 +01:00
sandrodachandClaude Opus 5.5 a9933b837e Merge branch 'theme/polarized-suri' into dev: Polarized and Suri themes
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m32s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 08:42:04 +01:00
sandrodachandClaude Opus 5.5 7bba174454 feat(pwa): start and keep working offline
The service worker now caches the app shell: page loads are network
first with the last index.html as fallback, hashed bundles come from the
cache, icons and manifest are refreshed in the background; API calls are
never intercepted. GET answers are kept per user in IndexedDB and served
when the server cannot be reached, so the app starts logged in with the
last known thoughts, tasks and lists. Captured thoughts and checked tasks
or list items go to an outbox that is sent in order when the connection
returns (also at start and every 30 s). A banner shows offline state and
waiting changes. Logging out clears cache and outbox.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 08:11:47 +01:00
sandrodachandClaude Opus 5.5 5e20710aa7 feat(auth): reset a forgotten password by mail
"Passwort vergessen?" appears on the login screen when SMTP and BASE_URL
are configured. The request always gets the same answer and sends the mail
in the background (at most every 2 minutes per account). The link holds a
random token valid once for one hour; only its SHA-256 is stored. Setting
the new password invalidates all open links and ends every session. The
app removes the token from the address bar and offers a way back for
expired links.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 08:06:56 +01:00
sandrodachandClaude Opus 5.5 677fe0fc0a feat(workspace): backlinks at the end of a note
GET /documents/{id}/backlinks lists the notes the user can open whose
blocks link [[Title]] (also |alias and #section, case-insensitive),
excluding the note itself and the trash. The collapsible "Verlinkt auf
diese Notiz" section shows each note with folder and the linking bullets;
a click jumps straight to the bullet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 08:00:57 +01:00
sandrodach 8619008aaa feat(theme): add Polarized and Suri purple dark themes 2026-10-29 07:58:33 +01:00