Commit Graph
43 Commits
Author SHA1 Message Date
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 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 83408d120d fix(workspace): more room for notes on phones
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m57s
Almost no side margin, 14 px indent per level (22 px from tablet width
on), zoom and delete buttons only take width in the active row. Very deep
rows keep about 14rem and the note scrolls sideways instead of squeezing
the text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 23:55:00 +01:00
sandrodachandClaude Opus 5.5 1632dd22c4 fix(workspace): English slash commands, short texts, wider menu
/image replaces /bild (aliases bild/foto keep working), shorter
descriptions for /link, /image, /audio, /diktat; the menu is wider, the
command never wraps and long descriptions are cut off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 23:47:38 +01:00
sandrodachandClaude Opus 5.5 3f2bc96732 feat(workspace): dictation via /diktat (M4)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m59s
/diktat (only in an empty bullet, only with voice input available)
listens right away; the bullet becomes one button with the live wave
across it and a translucent "Stopp" on top. A tap ends it and the
recognised text lands in the bullet as plain text. Uses the configured
speech recognition (own Whisper server or the browser); Esc cancels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 23:30:15 +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 cc68d3f334 fix(workspace): keep the cursor in a block that turns into a code block
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m58s
Converting via /code or ``` swapped the text field for the code editor's
and left the focus nowhere, so further typing triggered app shortcuts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 22:48:35 +01:00
sandrodach ff53f06991 feat(workspace): code block with language picker and live highlighting 2026-10-29 22:18:03 +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 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 1bd38f4d50 feat(notes): presence as avatar stack, drop guide lines, fix stuck bullet focus
- Leaving a block now clears its focus, so the bullet no longer stays highlighted
- Remove the vertical indentation guide lines
- Who has the note open: up to 3 overlapping avatars, "+n", full list on hover
- Shared AvatarStack component; UserAvatar gets xxs size and optional title

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 20:26:55 +01:00
sandrodachandClaude Opus 5.5 f82ab2fd32 fix: mobile layout, task clicks, list tab corners, hashtags in URLs
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m25s
Mobile
- Plus button in triage did nothing: the stored action returned the
  capture function instead of calling it
- Workspace: tabs share the full width; save status sits as an icon next
  to the note title instead of wrapping into its own row; "Neue Notiz" /
  "Neuer Ordner" only in the top menu (and +), not repeated in the list
- Outliner fields measured while hidden stayed one line high (cut-off
  callout); they are measured again when their width changes
- Task dialog: scrolls in a div instead of a fieldset, height in dvh,
  notes editor grows with its text, so long notes are fully reachable

Desktop
- Delete button of the selected task/shopping list sits inside the tab as
  its own rounded button (matches rounded themes like Soft)

Both
- Tasks sometimes did not open: every reload after an action replaced the
  list with a loading placeholder, swallowing clicks; reloads are now
  silent after the first load of a list, stale responses are dropped
- Hashtags need whitespace or "(" before "#", so URL anchors are no
  longer tags (server, browser); one-time cleanup of stored anchor tags

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 16:50:51 +01:00
sandrodachandClaude Sonnet 5.5 be85ea3093 feat(notes): jump to the task after converting; "Erweitert" badge opens it
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m20s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 15:51:37 +01:00
sandrodachandClaude Opus 5.5 aa397c18cd feat(notes): show block locks and presence, conflict copies with accept/discard, undo/redo
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m21s
Phase 3 of the collaboration plan:
- Blocks held by someone else show a lock with the name and are read-only;
  Enter in such a block adds a new block below. Delete, merge, indent and
  drag are not started when a involved block (or one in its branch) is
  locked; a short notice explains why (fixes FLAW-25).
- Presence: the editor header lists who else has the note open.
- Conflict copies are highlighted ("Konflikt – Version von …") with
  Übernehmen (replaces the original or the title) and Verwerfen. Both check
  the locks of the original and of the copy first.
- Undo/redo of own changes (Ctrl/Cmd+Z, Ctrl+Shift+Z, Ctrl+Y, beforeinput
  history events): typing is grouped per block until a 1 s pause, up to 200
  steps per tab; a step is skipped with a notice if someone else changed or
  holds the block meanwhile. New clearConflict props patch on the server.
- New blocks get focus synchronously on mount (fixes FLAW-26).
- Fix: after reopening a note from local storage the engine polled every
  30 s instead of 3 s until the next change, because the delay was decided
  before the first response told it the note is shared.
- Tests: undo/conflict engine tests, lock/undo/conflict UI tests and
  e2e/lock.e2e.mjs (two browsers); all three browser tests pass against a
  freshly built image.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 13:44:27 +01:00
sandrodachandClaude Opus 5.5 2b5291dc7b fix(workspace): caret at click position, no grey row highlight, hover-only collapse toggles
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 59s
- Clicking into a bullet places the caret where the mouse was, mapped
  from the rendered markdown layer back to the raw text, instead of
  always jumping to the end.
- Remove the grey background on focused and hovered rows and on the
  bullet handle.
- Collapse/expand chevrons are only shown while hovering the row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 09:19:35 +01:00
sandrodachandClaude Sonnet 5.5 b4c8577a61 fix(workspace): make Backspace merge work for untyped blocks and blocks with children
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 57s
The merge only applied to a fixed list of block types, so legacy blocks
without a type were ignored, and blocks with children were rejected.
Now only code/divider/table/progress are excluded and children move up
under the previous block. The focused bullet dot is also neutral now.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 08:53:35 +01:00
sandrodachandClaude Sonnet 5.5 c7e05b385c feat(workspace): merge bullet on Backspace, render hashtags inline
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m8s
- Backspace at the start of a non-empty bullet appends its text to the
  previous visible bullet (skipped for blocks with children and for
  code/divider/table/progress blocks).
- Hashtags are rendered inline as clickable chips instead of a badge row
  below the text, so lines no longer grow taller.
- Targeted/highlighted bullets use a neutral background instead of accent.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 08:31:25 +01:00
sandrodach 6896a29285 chore(workspace): remove placeholder text from first bulletpoint
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 59s
2026-10-27 21:48:43 +01:00
sandrodach c85f31eee5 fix(workspace): enable clicking into empty bulletpoint to focus cursor
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 59s
2026-10-27 21:33:18 +01:00
sandrodach 1c71b09f20 feat(workspace): hide bullet point on empty blocks unless hovered
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m0s
2026-10-27 21:29:05 +01:00
sandrodach 6a261e3453 feat(workspace): intelligent multi-line clipboard paste with markdown prefix & indentation parsing
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m2s
2026-10-27 21:27:01 +01:00
sandrodach fdbf691a8d feat(workspace): split bulletpoint paragraph at cursor position on Enter
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 59s
2026-10-27 21:17:12 +01:00
sandrodach 5cf6b59377 feat(tasks): refine enhanced task linking, outliner badge positioning, completion sync and unlink behavior
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 59s
2026-10-27 21:09:25 +01:00
sandrodach 63a5885155 fix(workspace): place cursor at end of line when jumping or clicking into bullet point
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 59s
2026-10-27 20:55:07 +01:00
sandrodach 94acb2638e fix(workspace): fix outliner cursor focus, enhanced task linking, nav order and Hauptebene drop zone
MindSift CI & Docker Release / Build, Test in Container & Push (push) Failing after 19s
2026-10-27 20:26:45 +01:00
sandrodach d39d1d1122 feat: complete workspace, triage, outliner and sharing overhaul (tasks 1-26)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 57s
2026-10-27 19:46:46 +01:00
sandrodach bce103e2c6 feat(outliner): prevent creating extra empty block on enter on last empty root bullet
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 59s
2026-10-27 17:43:20 +01:00
sandrodach 122ebccf8d refactor(outliner): make bullet point the drag handle and remove separate grip icon
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m2s
2026-10-27 17:41:25 +01:00
sandrodach fd89f92b0c feat(outliner): outdent empty bulletpoint on enter
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m2s
2026-10-27 17:31:08 +01:00
sandrodach 04fa774d10 refactor(collab): remove live document collaboration and enforce strictly read-only sharing
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m2s
2026-10-27 17:08:38 +01:00
sandrodach ee8d586e2f style(collab): right-align lock badge without shifting lines and highlight locked block with grey background
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 59s
2026-10-27 15:33:38 +01:00
sandrodach a1c7a65d84 fix(collab): fix corporate SSE fallback, realtime lock propagation and prevent stale overwrite
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m1s
2026-10-27 15:21:05 +01:00
sandrodach 0e06cc5577 feat(collab): redesign note collaboration with REST auto-save, opt-in live session, and block locking
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 59s
2026-10-27 14:02:38 +01:00
sandrodach 4850f9dfad feat(workspace): recursive folder tree, link modal redesign, todo grouping & line jumping, hashtag child listing
MindSift CI & Docker Release / Build, Test in Container & Push (push) Failing after 23s
2026-10-27 07:09:48 +01:00
sandrodach cedf5aebff fix(sync): eliminate zombie focus, flush debounced state on window blur, remove stale closures and buffer ws messages
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 57s
2026-10-26 22:27:11 +01:00
sandrodach 06f5f7043c feat(workspace): add /link slash command with note selector and web link modal
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 58s
2026-10-26 22:19:53 +01:00
sandrodach 1bcf6b4f18 refactor(outliner): remove redundant /bullet slash command
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 58s
2026-10-26 22:14:20 +01:00
sandrodach 177e24fdc8 feat(workspace): add focus mode and hoisting zoom-in for outliner blocks
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 58s
- Click bullet point (•) or hover zoom icon to zoom into any block branch
- Render hoisted block as prominent heading in focus mode with direct editing
- Display clickable breadcrumb path leading back to ancestors or root document
- Render isolated subtree with visual level offset and bound indentation
2026-10-26 22:04:53 +01:00
sandrodach 95977ba15a feat(workspace): add real-time live cursor and presence tracking
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 56s
- Support ephemeral cursor_moved and client_left events in docroom Hub
- Keep active in-memory cursor presence map per document room
- Synchronize current presence state to newly connected WebSocket clients
- Allow read-only viewers to share cursor positions without document mutation rights
- Throttle frontend cursor move emissions to 100ms with instant blur cleanup
- Render active collaborator presence avatar pills in document header
- Display user-colored block indicator and non-destructive caret overlay with name tag
2026-10-26 21:57:19 +01:00
sandrodach 85e4010435 fix(workspace): restore theme design-system, fix 5x note creation, enforce privacy isolation, fix shared write permission, add drag-drop & slash-commands
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 57s
2026-10-26 21:41:27 +01:00
sandrodach 86867b0d6f feat(workspace): tabula-rasa outliner architecture, SQLite blocks/block_tags schema & echo-protected live room sync
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m12s
2026-10-26 21:14:06 +01:00