The Telegram bot token was a const in AddChannels(), and the Mistral API
key was baked into the embedded Provider.Mistral.toml resource.
- Wire AddChannels() through the existing (previously unused)
AddTelegramOptions(), which binds "Channels:Telegram" and validates on
start. TelegramOptions is resolved from IOptions<> so TelegramAdapter
and TelegramChannel are unchanged.
- Ship the embedded provider defaults with an empty ApiKey. Ollama's
placeholder is now a non-secret literal.
- Re-apply AddEnvironmentVariables() last in AddLunaConfiguration() so
env vars override the TOML sources; without this the embedded defaults
would shadow injected credentials.
Credentials are now supplied via Providers__Mistral__ApiKey and
Channels__Telegram__BotToken, or via ~/.luna/providers/*.toml overrides.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Introduce Luna.Identity project with user identity service, pairing code
generation, and channel linking. Channels (Telegram, CLI) now verify link
status before routing messages and prompt users to pair via the web
interface. WebChannel handles /link <channel-type> <code> commands to
complete the pairing flow.
Fix inverted expiration check in IsPairingCodeExpired that caused codes
to be treated as expired immediately after creation.
Define channel abstractions (IChannel, IChannelManager) with event-driven
message and connection handling. Implement ChannelManager for multi-channel
orchestration, CliChannel for terminal I/O, TelegramChannel with adapter
pattern for bot API integration, and WebChannel stub. Includes DI
registration and channel type enumeration.