Skip to content

Elixdo 2.0: mobile UI, MCP server, and code quality#2

Merged
brocla merged 22 commits into
mainfrom
two-oh
May 6, 2026
Merged

Elixdo 2.0: mobile UI, MCP server, and code quality#2
brocla merged 22 commits into
mainfrom
two-oh

Conversation

@brocla

@brocla brocla commented May 6, 2026

Copy link
Copy Markdown
Owner

Summary

  • Phases 1 & 2: Stripped legacy formatting features (prefix, bold, italic, highlight) to simplify the item model
  • Phases 3 & 4: Priority handle decorations (emoji priorities on drag handles) and sort-active-first toolbar action
  • Phases 5 & 5a: Responsive color picker and priority picker — desktop swatches/buttons, mobile bottom sheets
  • Phase 6: Embedded MCP server (JSON-RPC 2.0 over Streamable HTTP/SSE) for AI assistant access to list data — 7 tools: get_today, list_items, list_items_range, add_item, update_item, arrow_item, search_items
  • Phase 7: Voice input via Web Speech API
  • Refactors: Single source of truth for color/priority lists, emoji conversion centralized in Lists context, fetch_item extracted to shared helper, selected_items helper in LiveView, @moduledoc on domain modules, @moduledoc false on web modules

Test plan

  • Run mix test — full suite passes
  • Verify mobile bottom sheets for color and priority
  • Test MCP tools via claude mcp integration
  • Verify voice input on Android Chrome
  • Smoke test arrow-forward, search, and date navigation

🤖 Generated with Claude Code

Kevin Brown and others added 22 commits May 4, 2026 15:49
Deletes the prefix field and bold/italic/highlighted formatting fields
from the schema, API, toolbar, and templates. These features added
complexity without being used in practice. Two reversible migrations
drop the columns from the database.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Phase 3: Add priority field (❶❷❸⭐🔥) to list items. Priority
character replaces the drag handle and is always visible. Toolbar
group lets users assign priority to selected items; remove-formats
clears it. Arrow copies do not inherit priority.

Phase 4: Sort-active button in toolbar reorders the current day so
all active items come first, preserving within-group order, via the
existing reorder_items/PubSub path.

CSS fixes: priority characters always visible on desktop (specificity
fix), correct sizing and tight spacing on both desktop and mobile.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After applying a status, priority, color, or remove-formats action,
deselect all items automatically. Previously selection persisted until
the user manually deselected, which felt sticky after an action was
complete.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On mobile (pointer: coarse), desktop color swatches and priority buttons are
hidden and replaced with single-button triggers that open bottom sheets with
large tap targets. Desktop experience is unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds POST /api/v1/mcp behind existing AGENT_TOKEN auth. Exposes seven tools:
get_today, list_items, list_items_range, add_item, update_item, arrow_item,
search_items. No new infrastructure — routes through existing Lists context.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
notifications/initialized has no id field — none of the existing handlers
matched, causing Phoenix to return 400. This broke the MCP handshake after
initialize. Add a catch-all that returns 204 No Content for all notifications.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude Code sends Accept: text/event-stream per the MCP Streamable HTTP spec.
The old :api_auth pipeline rejected this with 406. Fix:
- New :mcp_auth pipeline that accepts both json and event-stream
- MCP route moved to its own scope using :mcp_auth
- respond/2 helper branches on Accept header: returns SSE (event: message\ndata:...)
  when client requests it, plain JSON otherwise

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
event-stream isn't in Phoenix's MIME registry so plug :accepts rejected SSE
requests. The MCP controller handles content negotiation itself via the
Accept header, so the pipeline doesn't need a MIME guard.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Mirror the LiveView behaviour: 🔥 → 🔥 etc. before storing. Body-absent
update_item calls (status/color-only) are unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…fications

Previously untested paths:
- list_items_range (basic + status filter)
- SSE response format when Accept: text/event-stream
- notifications/initialized returning 204

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Mic button in the add-item area uses the Web Speech API on Android Chrome.
Button is hidden on unsupported browsers via JS hook; phx-update="ignore"
keeps LiveView from resetting its visibility on DOM patches.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removes the toolbar select-all circle button, toggle_all event handler,
.select-btn CSS block, and its single test. The per-item select circles
and all toolbar actions are unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace text label with fisheye character ◉ and title="Goto Today"
- Move button to first position in toolbar-left (before search)
- Restyle to match search/sort buttons: neutral grey, bg-2, border-color
- Narrow width (26px) to fit icon without excess padding
- Fix MCP shortcode test to use shortcodes that exist in the emoji map

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…etch_item

- ListItem.colors/0 and color_strings/0 derive from the Ecto.Enum field;
  all callers (LiveView guards, template loops, MCP schema) now use these
- Emoji.convert moved into Lists.create_items/update_item — no entry point
  can forget it; removed 4 scattered call sites
- fetch_item extracted to ElixdoWeb.Api.Helpers — shared by both API controllers
- Today button: ◉ icon, toolbar-left, neutral style matching search/sort buttons
- Placeholder text changed to "New task..."
- Text entry box background set to black; font-size 20px desktop and mobile

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@brocla brocla merged commit 7080ded into main May 6, 2026
1 check passed
@brocla brocla deleted the two-oh branch May 6, 2026 21:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant