- detail banner timeAgo: SQLite timestamps are UTC without tz marker,
JS was parsing them as local. Fixed by appending Z when absent —
same pattern chat uses. "2h ago" for a 30s-old update is gone.
- banner Reload button now re-fires detail.opened so the collab-buckets
plugin clears the red dot on the board card and calls mark-card-seen.
Dismiss (×) still leaves the dot — that's the acknowledgement that
nothing was actually read.
- instrument /api/relay/poll with a sync_debug field so the JS can
console.debug what happened on the sync-events sub-request (status,
count, error body). Helps diagnose "no toast" reports.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- replace chat-bot sync notifications with a dedicated relay_sync_events
queue: POST/GET /api/sync-events, drained by /api/relay/poll and
surfaced as stacking toasts via caldav.js. Old /api/chat/bot removed,
bot=1 rows purged on bootstrap, orange bot rendering dropped from
relay UI. Chat thread stays clean.
- collab pull: fetch attachments BEFORE applying the body so the moment
state.cards reflects the new reference the file is on disk. Fixes the
"preview shows broken/missing image, editor shows it" race where the
browser cached the 404 between attachment landing and user re-render.
- detail stale banner now compares title/body/color/tags in addition to
updated_at — robust against second-granularity timestamp collisions
and any other case where updated_at doesn't tick but content differs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New tooltip.js module with styled tooltips (data-tip) and multi-line
inline help (data-help). Migrates all ~70 native title attributes
across index.php, JS modules, and all plugins. Adds inline help on
9 strategic UI elements (split, superview, zen, extract, assets, etc).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>