ttyms 0.1.5

A secure terminal client for Microsoft Teams
Documentation
# ttyms Roadmap

Feature roadmap for the terminal Microsoft Teams client. Most features below are achievable using existing [Microsoft Graph API](https://learn.microsoft.com/en-us/graph/api/resources/teams-api-overview) endpoints with delegated permissions. Items marked โŒ are not feasible with current API capabilities.

---

## โœ… Shipped

- 1:1 chat messaging (send/receive)
- Group chat messaging
- New chat creation with user search + autocomplete
- Device code flow + PKCE browser flow authentication
- Secure token storage (OS keyring + file fallback with zeroize)
- Auto-refresh (15s interval)
- Vim-style keyboard navigation
- **Unread indicators & badge counts** โ€” per-chat unread count + total in header
- **Message reactions** โ€” display reactions inline, add reactions via keyboard picker (๐Ÿ‘โค๏ธ๐Ÿ˜‚๐Ÿ˜ฎ๐Ÿ˜ข๐Ÿ˜ก)
- **Rich text rendering** โ€” bold, italic, code, links rendered with terminal formatting
- **Message read receipts** โ€” chats marked as read when viewed
- **User presence / status** โ€” see availability (๐ŸŸข๐Ÿ”ดโ›”๐ŸŸกโšซ) for contacts and own status
- **Set your own presence** โ€” change status via presence picker dialog
- **New message notification** โ€” terminal bell on incoming messages
- **List joined teams** โ€” browse all teams in tabbed Teams view
- **Channel browsing** โ€” list channels within a team (standard + private)
- **Channel messages** โ€” read and post messages in team channels
- **Tabbed UI** โ€” switch between Chats and Teams views with 1/2 keys
- **Reply to messages** โ€” quote-reply via `r` key when message selected (chat + channel)
- **Edit / delete messages** โ€” edit own messages with `w`, soft-delete with `d`
- **Message pagination** โ€” scroll up to load older messages via `@odata.nextLink`
- **Homebrew distribution** โ€” `brew install davidkaya/tap/ttyms` with pre-built macOS binaries
- **Channel member list** โ€” toggle member sidebar with `m` key, owners marked with ๐Ÿ‘‘
- **Settings dialog** โ€” configurable refresh interval via in-app settings
- **Delta-based message sync** โ€” incremental message updates via Graph delta queries
- **Message search** โ€” full-text search across chats via Microsoft Search API (`/search/query`)
- **Chat management** โ€” rename group chats, view/add/remove members, leave chats via `g` key
- **Command palette** โ€” `Ctrl+P` fuzzy-find across chats, channels, and actions
- **Share files in chat** โ€” upload and share files via `f` key (up to 4MB, OneDrive-backed)

---

## ๐Ÿ”ฅ Phase 1 โ€” Core Messaging Polish

~~Essential improvements to make daily use practical.~~ **SHIPPED**

### ~~Unread indicators & badge counts~~ โœ…
### ~~Message read receipts~~ โœ…
### ~~Message reactions (emoji)~~ โœ…
### ~~Rich text rendering~~ โœ…
### ~~Reply to specific messages~~ โœ…
### ~~Delete / edit sent messages~~ โœ…
### ~~Message pagination (infinite scroll)~~ โœ…

---

## ๐ŸŸก Phase 2 โ€” Presence & Notifications

~~Make the client feel alive and connected.~~ **SHIPPED**

### ~~User presence / status~~ โœ…
### ~~Set your own presence~~ โœ…
### ~~Desktop notifications~~ โœ… (terminal bell on new messages)

### ~~Typing indicators~~ โŒ
~~Show "User is typingโ€ฆ" and broadcast your own typing state.~~
- **Not feasible** โ€” Microsoft Graph API does not expose typing indicator endpoints for reading or broadcasting typing state. Would require SignalR/WebSocket which is not available for 3rd-party clients.

---

## ๐ŸŸข Phase 3 โ€” Teams & Channels

~~Extend beyond 1:1/group chats into full Teams workspace support.~~ **SHIPPED**

### ~~List joined teams~~ โœ…
### ~~Channel browsing~~ โœ…
### ~~Channel messages~~ โœ… (read and send)
### ~~Channel member list~~ โœ…

---

## ๐Ÿ”ต Phase 4 โ€” File Sharing & Media

### ~~Share files in chat~~ โœ…
~~Upload and share files within a chat conversation.~~
- ~~`PUT /me/drive/root:/Microsoft Teams Chat Files/{filename}:/content` (upload to OneDrive)~~
- ~~Send message with `attachment` referencing the uploaded file~~
- ~~Scope: `Files.ReadWrite`~~

### View shared files
List files shared in a chat and open them (launch in browser or download).
- `GET /me/chats/{id}/tabs` โ€” pinned files
- Parse `attachment` objects from messages
- `GET /drives/{id}/items/{id}` โ€” download URL

### Image previews
Render inline images in the terminal using unicode block characters or sixel protocol (for supported terminals).
- `GET /me/chats/{id}/messages/{id}/hostedContents/{id}` โ€” fetch hosted image content

---

## ๐ŸŸฃ Phase 5 โ€” Real-time & Advanced

### ~~WebSocket/SignalR real-time messages~~ โ†’ Delta-based sync โœ…
~~Replace polling with real-time message delivery using Graph change notifications.~~
- True WebSocket/SignalR notifications require a public webhook URL (not feasible for terminal clients)
- Implemented **delta queries** (`/chats/{id}/messages/delta`) for incremental message sync
- Only new/changed messages are fetched on each poll cycle, dramatically reducing API calls
- Delta tokens stored per-chat for efficient incremental updates

### ~~Search messages~~ โœ…
~~Full-text search across all chats and channels.~~
- ~~`GET /me/chats/{id}/messages?$search="query"` (limited)~~
- ~~`POST /search/query` โ€” Microsoft Search API with `chatMessage` entity type~~
- ~~Scope: `Chat.Read`~~

### ~~Chat management~~ โœ…
~~Rename group chats, add/remove members, leave a chat.~~
- ~~`PATCH /me/chats/{id}` โ€” update topic~~
- ~~`POST /me/chats/{id}/members` โ€” add member~~
- ~~`DELETE /me/chats/{id}/members/{id}` โ€” remove member~~
- ~~`DELETE /me/chats/{id}/members/{myId}` โ€” leave chat~~

### Create group chats
Create new group conversations (not just 1:1).
- `POST /chats` with `chatType: "group"` and multiple members
- Already partially implemented โ€” extend `create_chat()` to accept multiple participants

### Pin / archive chats
Pin important chats to the top, archive inactive ones.
- `POST /me/chats/{id}/pinnedMessages` โ€” pin a message
- `PATCH /me/chats/{id}` โ€” hide/archive

### Contact / people list
Browse your frequent contacts and org directory.
- `GET /me/people` โ€” ranked relevant contacts
- `GET /me/contacts` โ€” address book
- Scope: `People.Read`

---

## ๐Ÿงช Phase 6 โ€” Power User Features

### Multiple account support
Switch between different Microsoft 365 tenants/accounts.
- Store multiple token sets in keyring with tenant-scoped keys
- Config: `[[accounts]]` array in TOML

### Chat export
Export chat history to markdown, JSON, or plain text.
- Paginate through `GET /me/chats/{id}/messages` and serialize locally

### Keyboard macro / shortcuts customization
User-configurable keybindings via `config.toml`.
- No API โ€” local config feature

### Theme customization
User-selectable color themes (dark, light, solarized, nord, etc.).
- No API โ€” ratatui styling via config

### Mouse support
Click to select chats, scroll messages, focus input.
- No API โ€” crossterm mouse event handling (already available in the dependency)

### ~~Command palette~~ โœ…
~~`Ctrl+P` fuzzy-find across chats, channels, people, and actions.~~
- ~~Combine results from `/me/chats`, `/me/joinedTeams`, `/me/people`~~

### Markdown message composition
Write messages in markdown, convert to Teams-compatible HTML before sending.
- `POST /me/chats/{id}/messages` with `contentType: "html"` and converted body

### Adaptive Card rendering
Render incoming Adaptive Cards (approval requests, forms, polls) as structured terminal UI.
- Parse `attachment` objects with `contentType: "application/vnd.microsoft.card.adaptive"`

---

## ๐Ÿ“ฆ Distribution

### ~~Homebrew (macOS)~~ โœ…
Publish ttyms as a Homebrew formula for easy installation on macOS.
- Create a Homebrew tap repository (`homebrew-tap`)
- Add formula with `cargo install` or pre-built binaries from GitHub Releases
- Support `brew install ttyms` for one-command installation
- Auto-update formula on new GitHub Releases via CI

---

## Scope Requirements Summary

Scopes needed beyond what's currently configured:

| Phase | Additional Scopes |
|-------|-------------------|
| 1 | โ€” (none, all within current scopes) |
| 2 | `Presence.Read`, `Presence.ReadWrite` (optional) |
| 3 | `Channel.ReadBasic.All`, `ChannelMessage.Read.All`, `ChannelMessage.Send`, `Team.ReadBasic.All` |
| 4 | `Files.ReadWrite` |
| 5 | `People.Read` |

---

## Priority Recommendation

For maximum impact with minimum effort:

1. **Unread indicators** โ€” biggest UX win, zero new API scopes
2. **Message reactions** โ€” makes the client feel complete
3. **Rich text rendering** โ€” no API changes, pure client-side improvement
4. **User presence** โ€” one new scope, huge quality-of-life improvement
5. **Teams & channels** โ€” opens up the full Teams experience