Files
openhuman/app/src/index.css
T
8aa5547af4 feat: Telegram managed login, channel messaging, and inbound agent loop (#338)
* feat: add managed Telegram login flow and API endpoints

- Introduced a new managed Telegram login flow, allowing users to link their Telegram accounts via a deep link.
- Added `telegram_login_start` and `telegram_login_check` functions to handle the creation of link tokens and status checks for user linking.
- Updated the API with new endpoints for managing Telegram login, including detailed response structures for link token creation and status verification.
- Enhanced the `.env.example` file to include a configuration option for the Telegram bot username, facilitating easier setup for developers.

* refactor: update Telegram integration to use core RPC for login flow

- Replaced the managed DM API with core RPC calls for initiating and checking Telegram login status.
- Introduced new API methods `telegramLoginStart` and `telegramLoginCheck` to handle link token creation and verification.
- Updated the TelegramConfig and MessagingPanel components to utilize the new login flow, enhancing the user experience and simplifying the codebase.
- Adjusted tests to reflect changes in the login process and ensure proper functionality.

* docs: update TODO list with new user interaction registration task for memory skill

* feat: add ChannelSetupModal for configuring channel integrations

- Introduced a new reusable modal component, ChannelSetupModal, for configuring channel integrations such as Telegram and Discord.
- The modal can be opened from the Skills page or Settings, enhancing user experience by providing a centralized configuration interface.
- Updated MessagingPanel and Skills components to integrate the new modal, allowing users to easily manage their channel settings.
- Implemented channel-specific configuration components for better modularity and maintainability.

* feat: add ChannelSetupModal for configuring channel integrations

- Introduced a new reusable modal component, ChannelSetupModal, for configuring channel integrations such as Telegram and Discord.
- The modal can be opened from the Skills page or Settings, enhancing user experience by providing a centralized configuration interface.
- Updated MessagingPanel and Skills components to integrate the new modal, allowing users to easily manage their channel settings.
- Implemented channel-specific configuration components for better modularity and maintainability.

* style: update channel components for improved UI consistency

- Refactored styles across various channel configuration components, including ChannelCapabilities, ChannelConfigPanel, ChannelFieldInput, ChannelSelector, DiscordConfig, TelegramConfig, and WebChannelConfig.
- Enhanced color schemes and layout for better readability and visual appeal, ensuring a cohesive design across the application.
- Updated status badge styles in definitions.ts to align with the new design standards.
- Improved error message visibility and loading indicators in Channels page for a more user-friendly experience.

* refactor: update WebChannelConfig and tests for improved clarity and functionality

- Renamed the `definition` prop in WebChannelConfig to `_definition` for clarity.
- Updated test cases in DiscordConfig and TelegramConfig to reflect changes in auth mode labels, ensuring accurate rendering of UI elements.
- Adjusted the TelegramConfig test to fix the click event on the connect button, enhancing test reliability.
- Modified channel definitions to streamline the managed DM auth mode, improving code organization and maintainability.

* fix: enhance WebGL error handling in MeshGradient and RotatingTetrahedronCanvas components

- Added error handling in the MeshGradient component to gracefully catch WebGL initialization failures, ensuring the app remains functional when the GPU context is unavailable.
- Updated the RotatingTetrahedronCanvas component to verify WebGL context availability before initializing the renderer, preventing crashes and improving user experience.
- Modified channel definitions to update auth mode labels for clarity and consistency across the application.

* style: update RotatingTetrahedronCanvas colors and animation speed

- Changed fill and edge colors in the RotatingTetrahedronCanvas component for improved visual appeal.
- Adjusted opacity of the fill material to enhance transparency effects.
- Introduced a speed multiplier for rotation animations, allowing for more dynamic visual effects.

* refactor: improve WebGL error handling and cleanup in MeshGradient component

- Removed unused canvas reference and WebGL context probing to streamline the MeshGradient component.
- Enhanced error handling during shader compilation to throw an error when WebGL context may be lost, improving robustness.
- Wrapped initialization logic in a try-catch block to gracefully handle failures, ensuring the gradient functionality is disabled if initialization fails.

* refactor: simplify Telegram login flow by removing unused link token check

- Removed the `check_channel_link_status` method from the `BackendOAuthClient`, streamlining the authentication process.
- Updated `telegram_login_check` to directly fetch the user profile and determine link status based on the presence of `telegramId`, enhancing clarity and reducing complexity.
- Adjusted logging to reflect the new flow and ensure accurate debugging information.

* feat: enhance JSON-RPC method invocation with session expiration handling

- Added logic to automatically clear stored session on receiving a 401 error from the backend, improving user experience by ensuring users are redirected to the login page when their session expires.
- Introduced a helper function to identify session expiration errors, enhancing code clarity and maintainability.
- Refactored the `invoke_method` function to incorporate this new error handling mechanism, ensuring robust session management during RPC calls.

* style: update app-dotted-canvas background gradient for improved visibility

- Changed the radial gradient background color in the app-dotted-canvas from rgba(0, 0, 0, 0.2) to rgba(0, 0, 0, 0.5), enhancing the contrast and overall visual appeal of the component.

* feat: implement channel messaging API with end-to-end testing script

- Added a new script `test-channel-messaging.sh` for end-to-end testing of message sending to Telegram via the backend API.
- Implemented new backend API methods for sending messages, reactions, creating threads, updating threads, and listing threads in channels.
- Enhanced the `BackendOAuthClient` with methods to handle channel messaging operations.
- Updated controller schemas and handlers to support the new messaging functionalities, ensuring robust interaction with the backend.
- Improved logging for better debugging and tracking of channel operations.

* feat: add test-channel-receive script for real-time channel message listening

- Introduced a new script `test-channel-receive.mjs` that connects to the backend Socket.IO server and listens for incoming channel messages.
- Implemented session token retrieval and validation against the backend, ensuring secure message handling.
- Added options for debugging and sending test messages, enhancing the script's usability for testing purposes.
- Improved logging for better visibility of connection status and incoming messages.

* feat: implement inbound channel message handling for real-time responses

- Added functionality to handle inbound messages from channels (e.g., Telegram, Discord) by introducing the `handle_channel_inbound_message` function.
- Implemented agent inference loop to process messages and send replies back to the originating channel via the REST API.
- Enhanced logging for better tracking of message reception and response handling.
- Integrated timeout handling to manage long-running requests effectively.

* style: fix prettier formatting for channel components

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 22:08:17 -07:00

382 lines
8.5 KiB
CSS

/* Import Google Fonts for trust and professionalism */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600&display=swap');
/* Tailwind CSS imports */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Base layer - Typography and fundamental styles */
@layer base {
/* Set default font and improve text rendering */
html {
font-family:
'Inter',
-apple-system,
BlinkMacSystemFont,
'SF Pro Display',
'SF Pro Text',
system-ui,
'Segoe UI',
Roboto,
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
color: #171717;
}
body {
@apply text-stone-900;
@apply font-sans;
line-height: 1.6;
background: #f5f5f5;
color: #171717;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
* {
color: inherit;
}
/* Heading hierarchy for clear information architecture */
h1,
h2,
h3,
h4,
h5,
h6 {
@apply font-sans font-semibold;
@apply text-stone-900;
line-height: 1.2;
}
h1 {
@apply text-3xl lg:text-4xl;
}
h2 {
@apply text-2xl lg:text-3xl;
}
h3 {
@apply text-xl lg:text-2xl;
}
h4 {
@apply text-lg lg:text-xl;
}
/* Complete focus outline suppression - no borders, no rings, no outlines */
* {
outline: none !important;
-webkit-tap-highlight-color: transparent !important;
}
*:focus {
outline: none !important;
box-shadow: none !important;
border: inherit !important;
border-color: inherit !important;
}
/* Specific overrides for common elements that might show blue outlines */
button:focus,
a:focus,
input:focus,
textarea:focus,
select:focus,
[role='button']:focus,
[tabindex]:focus {
outline: none !important;
box-shadow: none !important;
border-color: inherit !important;
}
/* Smooth scrolling */
html {
scroll-behavior: smooth;
}
}
/* Component layer - Reusable patterns */
@layer components {
/* Button variants for consistent interaction design */
.btn-primary {
@apply bg-primary-500 hover:bg-primary-600 active:bg-primary-700;
@apply text-white font-medium;
@apply px-4 py-2 rounded-lg;
@apply transition-all duration-200 ease-in-out;
@apply shadow-soft hover:shadow-medium;
@apply focus:outline-none;
@apply disabled:opacity-50 disabled:cursor-not-allowed;
}
.btn-secondary {
@apply bg-stone-900 hover:bg-stone-800 active:bg-stone-700;
@apply text-white font-medium;
@apply px-4 py-2 rounded-lg border border-stone-300;
@apply transition-all duration-200 ease-in-out;
@apply focus:outline-none;
}
.btn-success {
@apply bg-sage-500 hover:bg-sage-600 active:bg-sage-700;
@apply text-white font-medium;
@apply px-4 py-2 rounded-lg;
@apply transition-all duration-200 ease-in-out;
@apply shadow-soft hover:shadow-medium;
@apply focus:outline-none;
}
.btn-danger {
@apply bg-coral-500 hover:bg-coral-600 active:bg-coral-700;
@apply text-white font-medium;
@apply px-4 py-2 rounded-lg;
@apply transition-all duration-200 ease-in-out;
@apply shadow-soft hover:shadow-medium;
@apply focus:outline-none;
}
/* Card components for content organization */
.card {
@apply bg-white rounded-xl shadow-soft border border-stone-200;
@apply p-6 text-stone-900;
@apply transition-shadow duration-200;
}
.card-hover {
@apply card hover:shadow-medium;
}
.app-dotted-canvas {
background-color: transparent;
background-image: radial-gradient(circle at center, rgba(0, 0, 0, 0.5) 1px, transparent 1px);
background-size: 18px 18px;
background-position: 0 0;
}
/* Input components with consistent styling */
.input-primary {
@apply w-full px-4 py-3 rounded-lg;
@apply border border-stone-200 focus:border-primary-500;
@apply bg-white text-stone-900 placeholder-stone-400;
@apply transition-colors duration-200;
@apply focus:outline-none;
}
/* Status indicators */
.status-online {
@apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium;
@apply bg-sage-100 text-sage-700;
}
.status-offline {
@apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium;
@apply bg-stone-100 text-stone-600;
}
.status-warning {
@apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium;
@apply bg-amber-100 text-amber-700;
}
/* Navigation styles */
.nav-item {
@apply flex items-center px-4 py-2 text-sm font-medium rounded-lg;
@apply text-stone-600 hover:text-stone-900 hover:bg-stone-100;
@apply transition-colors duration-150;
}
.nav-item-active {
@apply nav-item bg-stone-100 text-stone-900;
}
/* Message/chat specific styles */
.message-bubble {
@apply max-w-xs lg:max-w-md px-4 py-2 rounded-2xl;
@apply break-words;
}
.message-sent {
@apply message-bubble bg-primary-500 text-white ml-auto;
}
.message-received {
@apply message-bubble bg-stone-200/80 text-stone-900;
}
/* Loading states */
.loading-pulse {
@apply animate-pulse bg-stone-100 rounded;
}
/* Crypto price styling */
.price-positive {
@apply text-market-bullish font-mono font-medium;
}
.price-negative {
@apply text-market-bearish font-mono font-medium;
}
.price-neutral {
@apply text-market-neutral font-mono font-medium;
}
}
/* Utility layer - Custom utilities */
@layer utilities {
/* Scrollbar styling for better UX */
.scrollbar-thin {
scrollbar-width: thin;
scrollbar-color: rgb(163 163 163) transparent;
}
.scrollbar-thin::-webkit-scrollbar {
width: 6px;
}
.scrollbar-thin::-webkit-scrollbar-track {
background: transparent;
}
.scrollbar-thin::-webkit-scrollbar-thumb {
background-color: rgb(163 163 163);
border-radius: 3px;
}
.scrollbar-thin::-webkit-scrollbar-thumb:hover {
background-color: rgb(115 115 115);
}
/* Hide scrollbar while keeping scroll behavior */
.scrollbar-hide {
scrollbar-width: none;
-ms-overflow-style: none;
}
.scrollbar-hide::-webkit-scrollbar {
display: none;
}
/* Text selection styling */
.select-primary::selection {
@apply bg-primary-600 text-white;
}
/* Glass effect for light theme */
.glass {
backdrop-filter: blur(12px);
background: rgba(255, 255, 255, 0.8);
border: 1px solid rgba(0, 0, 0, 0.06);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
/* Animation utilities */
.animate-fade-in-up {
animation: fadeInUp 0.5s ease-out forwards;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Modal animations */
.animate-fade-in {
animation: fadeIn 0.2s ease-out forwards;
}
.animate-slide-up {
animation: slideUp 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Safe area padding for mobile devices */
.safe-area-padding {
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
padding-left: env(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
}
/* Skills table container */
.skills-table-container {
position: relative;
max-height: calc(3 * 2.5rem + 2.5rem + 1px); /* Header + 3 rows + border */
overflow: hidden;
display: flex;
flex-direction: column;
}
.skills-table-scroll {
overflow-y: auto;
overflow-x: hidden;
max-height: calc(3 * 2.5rem + 2.5rem + 1px);
}
.skills-table-header {
position: sticky;
top: 0;
z-index: 10;
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(8px);
}
/* Gradient fade overlay at bottom */
.skills-table-container::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 50px;
background: linear-gradient(to bottom, transparent, rgba(245, 245, 245, 0.9));
pointer-events: none;
z-index: 10;
}
/* Hover overlay */
.skills-table-overlay {
z-index: 20;
}
.skills-table-container:hover .skills-table-overlay {
opacity: 1;
pointer-events: auto;
}
}
/* Light mode (default) */
:root {
color-scheme: light;
}