# Package: dirigent_matrix

Matrix integration for Dirigent session sharing.

## Quick Facts
- **Type**: Library
- **Main Entry**: src/lib.rs
- **Dependencies**: matrix-sdk, dirigent_protocol, tokio, serde, thiserror, async-trait
- **Status**: Phase 1 -- Bot-mode session sharing

## Purpose

Provides bidirectional bridging between Dirigent sessions and Matrix rooms.
A session can be "shared" to a Matrix room, allowing Matrix users to send
messages to the agent and see responses in real-time.

## Architecture

### MatrixService (`service.rs`)
Central singleton owning the matrix-sdk Client. Handles:
- Bot authentication (login with username/password, session restore via SQLite store)
- Background sync loop for receiving Matrix events
- Share registry (tracks active session shares by connector_id + session_id)
- Room message dispatch to appropriate shares

### MatrixSessionShare (`share.rs`)
Bidirectional bridge for one (connector_id, session_id) to one Matrix room:
- **Dirigent to Matrix**: Subscribes to connector events, forwards completed assistant messages as m.notice
- **Matrix to Dirigent**: Receives room messages via MatrixService dispatch, sends ConnectorCommandProxy through mpsc channel
- Implements the `SessionShare` trait from dirigent_protocol

### MatrixConfig (`config.rs`)
Configuration parsed from `[matrix]` section in dirigent.toml:
- Homeserver URL, username, password source (env var or inline)
- Device ID for session persistence across restarts
- Display name, default invite list, store path

### Room Management (`room.rs`)
- Private, non-federated room creation for session shares
- Room naming conventions (`"Dirigent: <title>"`)

## Configuration

Identity and credentials live in an Account; sharing behavior in `[matrix]`:

```toml
[accounts.matrix-bot]
type = "matrix"
homeserver = "https://matrix.example.com"
username = "dirigent_bot"
device_id = "DIRIGENT_01"
display_name = "Dirigent Bot"

[accounts.matrix-bot.credentials.password]
source = "env"
key = "DIRIGENT_MATRIX_PASSWORD"

[matrix]
account = "matrix-bot"
default_invite = ["@user:example.com"]
store_path = "matrix/bot/store"
```

## Key Types
- `MatrixService` -- Singleton service, owns Client and share registry
- `MatrixSessionShare` -- Bidirectional session-to-room bridge
- `MatrixBehaviorConfig` -- Sharing behavior (account ref, invites, store path)
- `ConnectorCommandProxy` -- Message proxy decoupling from dirigent_core types
- `CreateRoomOptions` -- Room creation parameters

## Integration with CoreRuntime

The MatrixService is wired into CoreRuntime as an optional component (like archivist):
- `CoreRuntime::start_matrix_service()` -- Resolves Account from config, creates and starts service
- `CoreRuntime::create_matrix_share()` -- Creates room, starts bridge, spawns command proxy task
- `CoreRuntime::matrix_service()` -- Accessor for the running service

## Event Flow

```
Connector emits Event::MessageCompleted (role=assistant)
  -> MatrixSessionShare event forwarder task
    -> Sends m.notice to Matrix room

Matrix user sends message in room
  -> MatrixService sync loop receives SyncRoomMessageEvent
    -> Looks up share by room_id
      -> share.inject_message(text) -> ConnectorCommandProxy
        -> Proxy task translates to ConnectorCommand::SendMessage
          -> Connector processes message
```

## Related Packages
- **dirigent_protocol**: SessionShare trait, Event types consumed by share forwarder
- **dirigent_core**: CoreRuntime integration, ConnectorCommand, ConnectorHandle
- **dirigent_config**: Path resolution (DIRIGENT_DATA_DIR for SQLite store)
