Skip to content

feat: crates/trios-ext — Chrome Extension (Dioxus/Wasm) сайдбар с чатом и MCP-мостом ко всем crates #108

Description

@gHashTag

🧩 trios-ext: Chrome Extension на Rust + Dioxus + Wasm

Контекст

Нужно Chrome расширение на чистом Rust (без JS логики) — сайдбар с чатом и MCP-клиентом, который коннектится ко всем crates/* через trios-bus.

Не popup, не JS-обёртка — полноценный сайдбар как у Claude/Copilot в браузере.


Архитектура

crates/trios-ext/
├── Cargo.toml              # wasm32-unknown-unknown target
├── src/
│   ├── lib.rs              # wasm_bindgen entry point
│   ├── app.rs              # Dioxus root компонент
│   ├── components/
│   │   ├── sidebar.rs      # Сайдбар-контейнер (inject в страницу)
│   │   ├── chat.rs         # Чат с агентами
│   │   ├── agent_list.rs   # Список активных агентов
│   │   └── mcp_panel.rs    # MCP tools панель
│   └── mcp/
│       └── client.rs       # MCP клиент → trios-server через WebSocket
└── extension/
    ├── manifest.json       # MV3, side_panel permission
    ├── background.js       # Service worker (минимальный, только relay)
    ├── content.js          # Inject Wasm в страницу (минимальный)
    └── icons/

Детальное описание задач

1. Cargo.toml — новый crate в workspace

[package]
name = "trios-ext"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]

[dependencies]
dioxus = { version = "0.6", features = ["web"] }
wasm-bindgen = "0.2"
web-sys = { version = "0.3", features = ["WebSocket", "MessageEvent", "Window", "Document"] }
js-sys = "0.3"
trios-proto = { path = "../trios-proto" }   # Envelope<T> из RFC #107
serde = { version = "1", features = ["derive"] }
serde_json = "1"
gloo-net = "0.6"   # async fetch/ws для wasm

Добавить в корневой Cargo.toml:

members = [
  # ...existing...
  "crates/trios-ext",
]

2. manifest.json — MV3 с side_panel

{
  "manifest_version": 3,
  "name": "Trinity Agent Bridge",
  "version": "0.1.0",
  "description": "Trios AI agent sidebar — MCP bridge to all crates",
  "permissions": ["sidePanel", "storage", "activeTab"],
  "side_panel": {
    "default_path": "sidepanel.html"
  },
  "background": {
    "service_worker": "background.js",
    "type": "module"
  },
  "content_scripts": [{
    "matches": ["<all_urls>"],
    "js": ["content.js"]
  }],
  "action": {
    "default_title": "Open Trinity Sidebar"
  }
}

Важно: side_panel permission открывает постоянный сайдбар справа — НЕ popup.


3. Dioxus компоненты

app.rs — корневой компонент

  • use_signal для списка агентов Vec<AgentState>
  • use_signal для чат-истории Vec<ChatMessage>
  • WebSocket соединение к ws://localhost:PORT/mcp (порт из trios-server)
  • При старте — запрос списка агентов через MCP tools/list

components/sidebar.rs

  • Полная высота viewport
  • Три вкладки: Chat | Agents | MCP Tools
  • Кнопка collapse/expand (ширина 380px → 48px)
  • Статус соединения (🟢/🔴) в хедере

components/chat.rs

  • История сообщений с scroll-to-bottom
  • Инпут + Send кнопка
  • Отправка через trios-bus → AgentPayload::Task
  • Markdown рендер (через pulldown-cmark или wasm-compatible crate)
  • Показ agent_id отправителя в каждом сообщении

components/agent_list.rs

  • Карточка агента: имя, статус, последнее сообщение
  • Статусы: Idle | Working | Error — с цветовой индикацией
  • Клик на агента → открывает прямой чат с ним

components/mcp_panel.rs

  • Список доступных MCP tools из trios-server
  • Форма вызова tool с JSON параметрами
  • Результат tool вызова в форматированном виде

4. MCP клиент (mcp/client.rs)

WebSocket клиент к trios-server (уже существует в workspace):

pub struct McpClient {
    ws: WebSocket,
    pending: HashMap<String, oneshot::Sender<Value>>,
}

impl McpClient {
    pub async fn connect(url: &str) -> Result<Self>;
    pub async fn list_tools(&self) -> Result<Vec<McpTool>>;
    pub async fn call_tool(&self, name: &str, params: Value) -> Result<Value>;
    pub async fn list_agents(&self) -> Result<Vec<AgentState>>;
}

Протокол: Envelope<McpRequest> → Envelope<McpResponse> из trios-proto.


5. Build pipeline

Без .sh скриптов — только cargo команды:

# Сборка Wasm
cargo build -p trios-ext --target wasm32-unknown-unknown --release

# Bindgen (через cargo-component или wasm-bindgen-cli)
wasm-bindgen target/wasm32-unknown-unknown/release/trios_ext.wasm \
  --out-dir crates/trios-ext/extension/pkg \
  --target web

# Результат → crates/trios-ext/extension/ готово к загрузке в Chrome

Добавить в .github/workflows/ci.yml:

- name: Build trios-ext (wasm)
  run: |
    rustup target add wasm32-unknown-unknown
    cargo build -p trios-ext --target wasm32-unknown-unknown --release

6. sidepanel.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Trinity Agent Bridge</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div id="main"></div>
  <script type="module">
    import init from './pkg/trios_ext.js';
    await init();
  </script>
</body>
</html>

Вся UI логика в Rust/Dioxus — JS только для init().


Acceptance Criteria

  • cargo build -p trios-ext --target wasm32-unknown-unknown проходит без ошибок
  • Расширение загружается в Chrome через chrome://extensions → Load unpacked
  • Сайдбар открывается кнопкой расширения (не popup — именно side panel)
  • WebSocket соединяется к trios-server на localhost
  • Отображается список агентов из trios-agents
  • Чат отправляет Envelope<AgentPayload::Task> и получает Result
  • MCP панель показывает tools из trios-server
  • Нет .sh файлов
  • Нет unwrap() в публичных путях
  • cargo clippy -p trios-ext без warnings
  • Запись в .trinity/experience/trios-ext-YYYY-MM-DD.md

Зависимости от других Issues


Дополнительно

НЕ нужно:

  • ❌ Переписывать popup.html на Rust (если он уже есть — удалить)
  • ❌ Держать JS бизнес-логику
  • ❌ wasm-pack (использовать wasm-bindgen-cli напрямую)

Нужно:

  • ✅ Dioxus 0.6 (web feature)
  • ✅ Chrome Manifest V3 side_panel API
  • ✅ trios-proto для типизированных сообщений
  • ✅ gloo-net для async WebSocket в wasm

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions