Co-authored-by: Brice Carpentier <brice.carpentier@mistral.ai>
Co-authored-by: Clément Drouin <clement.drouin@mistral.ai>
Co-authored-by: Clément Sirieix <clement.sirieix@mistral.ai>
Co-authored-by: Kim-Adeline Miguel <51720070+kimadeline@users.noreply.github.com>
Co-authored-by: Lucas Marandat <31749711+lucasmrdt@users.noreply.github.com>
Co-authored-by: Michel Thomazo <51709227+michelTho@users.noreply.github.com>
Co-authored-by: Pierre Rossinès <pierre.rossines@mistral.ai>
Co-authored-by: Quentin <quentin.torroba@mistral.ai>
Co-authored-by: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
Mathias Gesbert 2026-04-29 17:20:27 +02:00 committed by GitHub
parent 632ea8c032
commit 1fd7eea289
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
63 changed files with 3482 additions and 301 deletions

View file

@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.9.1] - 2026-04-29
### Added
- Connector OAuth authentication flow in `/mcp` menu
- `ConfigPatch` operation types for Vibe Code
- `extra_headers` field to `ProviderConfig`
- Structured metadata on ACP tool results
- `vibe.user_cancelled_action` ACP telemetry coverage
- `vibe.new_session` telemetry event emitted whenever the session is reset
### Changed
- Migrated default model to `mistral-medium-3.5`
## [2.9.0] - 2026-04-28 ## [2.9.0] - 2026-04-28
### Added ### Added

View file

@ -439,7 +439,7 @@ Example custom agent configuration (`~/.vibe/agents/redteam.toml`):
```toml ```toml
# Custom agent configuration for red-teaming # Custom agent configuration for red-teaming
active_model = "devstral-2" active_model = "mistral-medium-3.5"
system_prompt_id = "redteam" system_prompt_id = "redteam"
# Disable some tools for this agent # Disable some tools for this agent

View file

@ -1,7 +1,7 @@
id = "mistral-vibe" id = "mistral-vibe"
name = "Mistral Vibe" name = "Mistral Vibe"
description = "Mistral's open-source coding assistant" description = "Mistral's open-source coding assistant"
version = "2.9.0" version = "2.9.1"
schema_version = 1 schema_version = 1
authors = ["Mistral AI"] authors = ["Mistral AI"]
repository = "https://github.com/mistralai/mistral-vibe" repository = "https://github.com/mistralai/mistral-vibe"
@ -11,25 +11,25 @@ name = "Mistral Vibe"
icon = "./icons/mistral_vibe.svg" icon = "./icons/mistral_vibe.svg"
[agent_servers.mistral-vibe.targets.darwin-aarch64] [agent_servers.mistral-vibe.targets.darwin-aarch64]
archive = "https://github.com/mistralai/mistral-vibe/releases/download/v2.9.0/vibe-acp-darwin-aarch64-2.9.0.zip" archive = "https://github.com/mistralai/mistral-vibe/releases/download/v2.9.1/vibe-acp-darwin-aarch64-2.9.1.zip"
cmd = "./vibe-acp" cmd = "./vibe-acp"
[agent_servers.mistral-vibe.targets.darwin-x86_64] [agent_servers.mistral-vibe.targets.darwin-x86_64]
archive = "https://github.com/mistralai/mistral-vibe/releases/download/v2.9.0/vibe-acp-darwin-x86_64-2.9.0.zip" archive = "https://github.com/mistralai/mistral-vibe/releases/download/v2.9.1/vibe-acp-darwin-x86_64-2.9.1.zip"
cmd = "./vibe-acp" cmd = "./vibe-acp"
[agent_servers.mistral-vibe.targets.linux-aarch64] [agent_servers.mistral-vibe.targets.linux-aarch64]
archive = "https://github.com/mistralai/mistral-vibe/releases/download/v2.9.0/vibe-acp-linux-aarch64-2.9.0.zip" archive = "https://github.com/mistralai/mistral-vibe/releases/download/v2.9.1/vibe-acp-linux-aarch64-2.9.1.zip"
cmd = "./vibe-acp" cmd = "./vibe-acp"
[agent_servers.mistral-vibe.targets.linux-x86_64] [agent_servers.mistral-vibe.targets.linux-x86_64]
archive = "https://github.com/mistralai/mistral-vibe/releases/download/v2.9.0/vibe-acp-linux-x86_64-2.9.0.zip" archive = "https://github.com/mistralai/mistral-vibe/releases/download/v2.9.1/vibe-acp-linux-x86_64-2.9.1.zip"
cmd = "./vibe-acp" cmd = "./vibe-acp"
[agent_servers.mistral-vibe.targets.windows-aarch64] [agent_servers.mistral-vibe.targets.windows-aarch64]
archive = "https://github.com/mistralai/mistral-vibe/releases/download/v2.9.0/vibe-acp-windows-aarch64-2.9.0.zip" archive = "https://github.com/mistralai/mistral-vibe/releases/download/v2.9.1/vibe-acp-windows-aarch64-2.9.1.zip"
cmd = "./vibe-acp.exe" cmd = "./vibe-acp.exe"
[agent_servers.mistral-vibe.targets.windows-x86_64] [agent_servers.mistral-vibe.targets.windows-x86_64]
archive = "https://github.com/mistralai/mistral-vibe/releases/download/v2.9.0/vibe-acp-windows-x86_64-2.9.0.zip" archive = "https://github.com/mistralai/mistral-vibe/releases/download/v2.9.1/vibe-acp-windows-x86_64-2.9.1.zip"
cmd = "./vibe-acp.exe" cmd = "./vibe-acp.exe"

View file

@ -1,6 +1,6 @@
[project] [project]
name = "mistral-vibe" name = "mistral-vibe"
version = "2.9.0" version = "2.9.1"
description = "Minimal CLI coding agent by Mistral" description = "Minimal CLI coding agent by Mistral"
readme = "README.md" readme = "README.md"
requires-python = ">=3.12" requires-python = ">=3.12"

View file

@ -34,7 +34,7 @@ class TestACPInitialize:
), ),
) )
assert response.agent_info == Implementation( assert response.agent_info == Implementation(
name="@mistralai/mistral-vibe", title="Mistral Vibe", version="2.9.0" name="@mistralai/mistral-vibe", title="Mistral Vibe", version="2.9.1"
) )
assert response.auth_methods == [] assert response.auth_methods == []
@ -62,7 +62,7 @@ class TestACPInitialize:
), ),
) )
assert response.agent_info == Implementation( assert response.agent_info == Implementation(
name="@mistralai/mistral-vibe", title="Mistral Vibe", version="2.9.0" name="@mistralai/mistral-vibe", title="Mistral Vibe", version="2.9.1"
) )
assert response.auth_methods is not None assert response.auth_methods is not None

View file

@ -288,7 +288,7 @@ class TestAcpSearchReplaceSessionUpdates:
assert update.content[0].new_text == "new text" assert update.content[0].new_text == "new text"
assert update.locations is not None assert update.locations is not None
assert len(update.locations) == 1 assert len(update.locations) == 1
assert update.locations[0].path == "/tmp/test.txt" assert update.locations[0].path == str(Path("/tmp/test.txt").resolve())
def test_tool_call_session_update_invalid_args(self) -> None: def test_tool_call_session_update_invalid_args(self) -> None:
class InvalidArgs: class InvalidArgs:
@ -302,7 +302,8 @@ class TestAcpSearchReplaceSessionUpdates:
) )
update = SearchReplace.tool_call_session_update(event) update = SearchReplace.tool_call_session_update(event)
assert update is None assert update is not None
assert update.title == "search_replace"
def test_tool_result_session_update(self) -> None: def test_tool_result_session_update(self) -> None:
search_replace_content = ( search_replace_content = (
@ -337,7 +338,7 @@ class TestAcpSearchReplaceSessionUpdates:
assert update.content[0].new_text == "new text" assert update.content[0].new_text == "new text"
assert update.locations is not None assert update.locations is not None
assert len(update.locations) == 1 assert len(update.locations) == 1
assert update.locations[0].path == "/tmp/test.txt" assert update.locations[0].path == str(Path("/tmp/test.txt").resolve())
def test_tool_result_session_update_invalid_result(self) -> None: def test_tool_result_session_update_invalid_result(self) -> None:
class InvalidResult: class InvalidResult:
@ -351,4 +352,5 @@ class TestAcpSearchReplaceSessionUpdates:
) )
update = SearchReplace.tool_result_session_update(event) update = SearchReplace.tool_result_session_update(event)
assert update is None assert update is not None
assert update.status == "failed"

View file

@ -2,8 +2,9 @@ from __future__ import annotations
from acp.schema import ToolCallStart from acp.schema import ToolCallStart
from vibe.acp.tools.builtins.read_file import ReadFile
from vibe.acp.tools.session_update import tool_call_session_update from vibe.acp.tools.session_update import tool_call_session_update
from vibe.core.tools.builtins.read_file import ReadFile, ReadFileArgs from vibe.core.tools.builtins.read_file import ReadFileArgs
from vibe.core.types import ToolCallEvent from vibe.core.types import ToolCallEvent

View file

@ -0,0 +1,296 @@
"""Tests for field_meta and locations in ACP tool overrides."""
from __future__ import annotations
from pathlib import Path
from acp.schema import ToolCallProgress, ToolCallStart
from pydantic import BaseModel
from vibe.acp.tools.builtins.grep import Grep
from vibe.acp.tools.builtins.read_file import ReadFile
from vibe.acp.tools.builtins.skill import Skill
from vibe.acp.tools.builtins.task import Task
from vibe.acp.tools.builtins.web_fetch import WebFetch
from vibe.acp.tools.builtins.web_search import WebSearch
from vibe.acp.tools.builtins.write_file import WriteFile
from vibe.acp.tools.session_update import (
tool_call_session_update,
tool_result_session_update,
)
from vibe.core.tools.builtins.grep import GrepArgs, GrepResult
from vibe.core.tools.builtins.read_file import ReadFileArgs, ReadFileResult
from vibe.core.tools.builtins.skill import SkillArgs, SkillResult
from vibe.core.tools.builtins.task import TaskArgs, TaskResult
from vibe.core.tools.builtins.webfetch import WebFetchArgs, WebFetchResult
from vibe.core.tools.builtins.websearch import (
WebSearchArgs,
WebSearchResult,
WebSearchSource,
)
from vibe.core.tools.builtins.write_file import WriteFileArgs, WriteFileResult
from vibe.core.types import ToolCallEvent, ToolResultEvent
def _call_event(
tool_name: str, tool_class: type, args: BaseModel | None
) -> ToolCallEvent:
return ToolCallEvent(
tool_name=tool_name, tool_call_id="tc-1", tool_class=tool_class, args=args
)
def _result_event(
tool_name: str, tool_class: type, result: BaseModel, *, error: str | None = None
) -> ToolResultEvent:
return ToolResultEvent(
tool_name=tool_name,
tool_call_id="tc-1",
tool_class=tool_class,
result=result,
error=error,
)
class TestGrepFieldMeta:
def test_call_meta_contains_query_and_tool_name(self) -> None:
event = _call_event("grep", Grep, GrepArgs(pattern="TODO", path="src"))
update = tool_call_session_update(event)
assert isinstance(update, ToolCallStart)
assert update.field_meta == {"tool_name": "grep", "query": "TODO"}
assert update.kind == "search"
def test_call_location_is_resolved_search_path(self) -> None:
event = _call_event("grep", Grep, GrepArgs(pattern="TODO", path="src"))
update = tool_call_session_update(event)
assert isinstance(update, ToolCallStart)
assert update.locations is not None
assert len(update.locations) == 1
assert update.locations[0].path == str(Path("src").resolve())
def test_result_locations_from_parsed_matches(self) -> None:
result = GrepResult(
matches="src/a.py:10:match\nsrc/b.py:20:other",
match_count=2,
was_truncated=False,
)
event = _result_event("grep", Grep, result)
update = tool_result_session_update(event)
assert isinstance(update, ToolCallProgress)
assert update.status == "completed"
assert update.locations is not None
assert len(update.locations) == 2
assert update.locations[0].path.endswith("src/a.py")
assert update.locations[0].line == 10
assert update.locations[1].path.endswith("src/b.py")
assert update.locations[1].line == 20
def test_fallback_on_none_args(self) -> None:
event = _call_event("grep", Grep, None)
update = tool_call_session_update(event)
assert isinstance(update, ToolCallStart)
assert update.kind == "search"
assert update.field_meta == {"tool_name": "grep"}
class TestReadFileFieldMeta:
def test_call_location_has_offset_and_limit(self) -> None:
event = _call_event(
"read_file", ReadFile, ReadFileArgs(path="/tmp/f.txt", offset=10, limit=50)
)
update = tool_call_session_update(event)
assert isinstance(update, ToolCallStart)
assert update.locations is not None
loc = update.locations[0]
assert loc.field_meta == {"type": "file_range", "offset": 10, "limit": 50}
assert update.field_meta == {"tool_name": "read_file"}
def test_call_defaults_offset_zero_limit_none(self) -> None:
event = _call_event("read_file", ReadFile, ReadFileArgs(path="/tmp/f.txt"))
update = tool_call_session_update(event)
assert isinstance(update, ToolCallStart)
assert update.locations is not None
loc = update.locations[0]
assert loc.field_meta == {"type": "file_range", "offset": 0, "limit": None}
def test_result_location_has_offset_and_lines_read(self) -> None:
result = ReadFileResult(
path="/tmp/f.txt",
content="line1\nline2\nline3\n",
lines_read=3,
was_truncated=False,
offset=10,
)
event = _result_event("read_file", ReadFile, result)
update = tool_result_session_update(event)
assert isinstance(update, ToolCallProgress)
assert update.locations is not None
loc = update.locations[0]
assert loc.field_meta == {"type": "file_range", "offset": 10, "limit": 3}
class TestWebSearchFieldMeta:
def test_call_meta_contains_query(self) -> None:
event = _call_event(
"web_search", WebSearch, WebSearchArgs(query="python async")
)
update = tool_call_session_update(event)
assert isinstance(update, ToolCallStart)
assert update.field_meta == {"tool_name": "web_search", "query": "python async"}
assert update.kind == "search"
def test_result_locations_are_source_urls_with_titles(self) -> None:
result = WebSearchResult(
answer="found it",
sources=[
WebSearchSource(title="Docs", url="https://docs.python.org"),
WebSearchSource(title="Blog", url="https://blog.example.com"),
],
)
event = _result_event("web_search", WebSearch, result)
update = tool_result_session_update(event)
assert isinstance(update, ToolCallProgress)
assert update.locations is not None
assert len(update.locations) == 2
assert update.locations[0].path == "https://docs.python.org"
assert update.locations[0].field_meta == {"type": "url", "title": "Docs"}
assert update.locations[1].path == "https://blog.example.com"
assert update.locations[1].field_meta == {"type": "url", "title": "Blog"}
class TestWebFetchFieldMeta:
def test_call_location_is_normalized_url(self) -> None:
event = _call_event("web_fetch", WebFetch, WebFetchArgs(url="example.com/page"))
update = tool_call_session_update(event)
assert isinstance(update, ToolCallStart)
assert update.kind == "fetch"
assert update.locations is not None
assert update.locations[0].path == "https://example.com/page"
def test_result_location_has_char_count_and_truncated(self) -> None:
result = WebFetchResult(
url="https://example.com",
content="hello world",
content_type="text/html",
was_truncated=True,
)
event = _result_event("web_fetch", WebFetch, result)
update = tool_result_session_update(event)
assert isinstance(update, ToolCallProgress)
assert update.locations is not None
loc = update.locations[0]
assert loc.path == "https://example.com"
assert loc.field_meta == {"type": "url", "char_count": 11, "truncated": True}
class TestSkillFieldMeta:
def test_call_meta_contains_skill_name(self) -> None:
event = _call_event("skill", Skill, SkillArgs(name="debug"))
update = tool_call_session_update(event)
assert isinstance(update, ToolCallStart)
assert update.field_meta == {"tool_name": "skill", "skill_name": "debug"}
assert update.kind == "read"
def test_result_has_skill_dir_location(self) -> None:
result = SkillResult(
name="debug", content="do things", skill_dir="/home/user/.vibe/skills/debug"
)
event = _result_event("skill", Skill, result)
update = tool_result_session_update(event)
assert isinstance(update, ToolCallProgress)
assert update.locations is not None
assert len(update.locations) == 1
assert update.locations[0].path == str(
Path("/home/user/.vibe/skills/debug").resolve()
)
assert update.field_meta == {"tool_name": "skill", "skill_name": "debug"}
def test_result_no_location_when_no_skill_dir(self) -> None:
result = SkillResult(name="debug", content="do things", skill_dir=None)
event = _result_event("skill", Skill, result)
update = tool_result_session_update(event)
assert isinstance(update, ToolCallProgress)
assert update.locations is None
class TestTaskFieldMeta:
def test_call_meta_contains_agent_and_task(self) -> None:
event = _call_event(
"task", Task, TaskArgs(task="explore codebase", agent="explore")
)
update = tool_call_session_update(event)
assert isinstance(update, ToolCallStart)
assert update.field_meta == {
"tool_name": "task",
"agent": "explore",
"task": "explore codebase",
}
def test_result_meta_contains_turn_count_and_response(self) -> None:
result = TaskResult(response="found 3 files", turns_used=5, completed=True)
event = _result_event("task", Task, result)
update = tool_result_session_update(event)
assert isinstance(update, ToolCallProgress)
assert update.status == "completed"
assert update.field_meta == {
"tool_name": "task",
"turn_count": 5,
"response": "found 3 files",
}
def test_result_failed_when_not_completed(self) -> None:
result = TaskResult(response="interrupted", turns_used=2, completed=False)
event = _result_event("task", Task, result)
update = tool_result_session_update(event)
assert isinstance(update, ToolCallProgress)
assert update.status == "failed"
class TestWriteFileFieldMeta:
def test_call_meta_contains_tool_name(self) -> None:
event = _call_event(
"write_file", WriteFile, WriteFileArgs(path="out.txt", content="hello")
)
update = tool_call_session_update(event)
assert isinstance(update, ToolCallStart)
assert update.field_meta == {"tool_name": "write_file"}
assert update.kind == "edit"
def test_call_location_is_resolved_path(self) -> None:
event = _call_event(
"write_file", WriteFile, WriteFileArgs(path="out.txt", content="hello")
)
update = tool_call_session_update(event)
assert isinstance(update, ToolCallStart)
assert update.locations is not None
assert update.locations[0].path == str(Path("out.txt").resolve())
def test_result_location_is_resolved_path(self) -> None:
result = WriteFileResult(
path="out.txt", content="hello", bytes_written=5, file_existed=False
)
event = _result_event("write_file", WriteFile, result)
update = tool_result_session_update(event)
assert isinstance(update, ToolCallProgress)
assert update.locations is not None
assert update.locations[0].path == str(Path("out.txt").resolve())

View file

@ -211,7 +211,7 @@ class TestAcpWriteFileSessionUpdates:
assert update.content[0].new_text == "Hello" assert update.content[0].new_text == "Hello"
assert update.locations is not None assert update.locations is not None
assert len(update.locations) == 1 assert len(update.locations) == 1
assert update.locations[0].path == "/tmp/test.txt" assert update.locations[0].path == str(Path("/tmp/test.txt").resolve())
def test_tool_call_session_update_invalid_args(self) -> None: def test_tool_call_session_update_invalid_args(self) -> None:
from vibe.core.types import FunctionCall, ToolCall from vibe.core.types import FunctionCall, ToolCall
@ -232,7 +232,8 @@ class TestAcpWriteFileSessionUpdates:
) )
update = WriteFile.tool_call_session_update(event) update = WriteFile.tool_call_session_update(event)
assert update is None assert update is not None
assert update.title == "write_file"
def test_tool_result_session_update(self) -> None: def test_tool_result_session_update(self) -> None:
result = WriteFileResult( result = WriteFileResult(
@ -260,7 +261,7 @@ class TestAcpWriteFileSessionUpdates:
assert update.content[0].new_text == "Hello" assert update.content[0].new_text == "Hello"
assert update.locations is not None assert update.locations is not None
assert len(update.locations) == 1 assert len(update.locations) == 1
assert update.locations[0].path == "/tmp/test.txt" assert update.locations[0].path == str(Path("/tmp/test.txt").resolve())
def test_tool_result_session_update_invalid_result(self) -> None: def test_tool_result_session_update_invalid_result(self) -> None:
class InvalidResult: class InvalidResult:
@ -274,4 +275,5 @@ class TestAcpWriteFileSessionUpdates:
) )
update = WriteFile.tool_result_session_update(event) update = WriteFile.tool_result_session_update(event)
assert update is None assert update is not None
assert update.status == "failed"

View file

@ -0,0 +1,368 @@
from __future__ import annotations
from typing import Any, cast
from unittest.mock import MagicMock, patch
import pytest
from textual.widgets import OptionList
from tests.stubs.fake_connector_registry import FakeConnectorRegistry
from vibe.cli.textual_ui.widgets.connector_auth_app import (
ConnectorAuthApp,
_AuthOptionId,
)
from vibe.core.tools.connectors.connector_registry import RemoteTool
def _make_registry(*, with_disconnected: bool = True) -> FakeConnectorRegistry:
connectors: dict[str, list[RemoteTool]] = {
"gmail": [RemoteTool(name="search", description="Search emails")]
}
if with_disconnected:
connectors["slack"] = []
return FakeConnectorRegistry(connectors=connectors)
def _make_app(
connector_name: str = "slack", registry: FakeConnectorRegistry | None = None
) -> ConnectorAuthApp:
reg = registry or _make_registry()
mgr = MagicMock()
return ConnectorAuthApp(
connector_name=connector_name, connector_registry=reg, tool_manager=mgr
)
class TestConnectorAuthAppInit:
def test_widget_id(self) -> None:
app = _make_app()
assert app.id == "connectorauth-app"
def test_stores_connector_name(self) -> None:
app = _make_app(connector_name="gmail")
assert app._connector_name == "gmail"
def test_initial_state(self) -> None:
app = _make_app()
assert app._auth_url is None
assert app._auth_url_visible is False
assert app._status_message is None
class TestAuthUrlFetched:
def test_auth_url_available_shows_menu(self) -> None:
app = _make_app()
option_list = MagicMock()
option_list.get_option_index.return_value = 2
detail = MagicMock()
help_widget = MagicMock()
def query(sel, *a, **kw): # type: ignore[no-untyped-def]
if sel is OptionList:
return option_list
s = str(sel)
if "detail" in s:
return detail
if "help" in s:
return help_widget
return MagicMock()
app.query_one = query # type: ignore[assignment]
app._on_auth_url_fetched("https://auth.example.com/oauth")
assert app._auth_url == "https://auth.example.com/oauth"
assert option_list.clear_options.called
assert option_list.add_option.call_count == 5
option_ids = [
call.args[0].id
for call in option_list.add_option.call_args_list
if hasattr(call.args[0], "id") and call.args[0].id
]
assert _AuthOptionId.OPEN in option_ids
assert _AuthOptionId.COPY in option_ids
assert _AuthOptionId.SHOW in option_ids
def test_auth_url_none_shows_no_auth_message(self) -> None:
app = _make_app()
option_list = MagicMock()
detail = MagicMock()
help_widget = MagicMock()
def query(sel, *a, **kw): # type: ignore[no-untyped-def]
if sel is OptionList:
return option_list
s = str(sel)
if "detail" in s:
return detail
if "help" in s:
return help_widget
return MagicMock()
app.query_one = query # type: ignore[assignment]
app._on_auth_url_fetched(None)
assert app._auth_url is None
last_option = option_list.add_option.call_args_list[-1].args[0]
assert "does not provide authentication" in str(last_option.prompt)
class TestAuthActions:
def test_open_browser_calls_webbrowser(self) -> None:
app = _make_app()
app._auth_url = "https://auth.example.com/oauth"
app.query_one = MagicMock()
with patch("vibe.cli.textual_ui.widgets.connector_auth_app.webbrowser") as wb:
app._open_browser()
wb.open.assert_called_once_with("https://auth.example.com/oauth")
assert app._status_message == "Opened in browser."
def test_open_browser_noop_without_url(self) -> None:
app = _make_app()
app._auth_url = None
with patch("vibe.cli.textual_ui.widgets.connector_auth_app.webbrowser") as wb:
app._open_browser()
wb.open.assert_not_called()
def test_copy_url_calls_clipboard(self) -> None:
app = cast(Any, _make_app())
app._auth_url = "https://auth.example.com/oauth"
with (
patch.object(
type(app), "app", new_callable=lambda: property(lambda s: MagicMock())
),
patch(
"vibe.cli.textual_ui.widgets.connector_auth_app.copy_text_to_clipboard"
) as copy_fn,
):
app._copy_url()
copy_fn.assert_called_once()
assert copy_fn.call_args.args[1] == "https://auth.example.com/oauth"
assert (
copy_fn.call_args.kwargs["success_message"]
== "Auth URL copied to clipboard"
)
def test_copy_url_noop_without_url(self) -> None:
app = _make_app()
app._auth_url = None
with patch(
"vibe.cli.textual_ui.widgets.connector_auth_app.copy_text_to_clipboard"
) as copy_fn:
app._copy_url()
copy_fn.assert_not_called()
def test_toggle_url_shows_then_hides(self) -> None:
app = cast(Any, _make_app())
app._auth_url = "https://auth.example.com/oauth"
detail = MagicMock()
app.query_one = lambda sel, *a, **kw: detail
assert app._auth_url_visible is False
app._toggle_url()
assert app._auth_url_visible is True
text = detail.update.call_args.args[0]
assert "https://auth.example.com/oauth" in text
assert "Once authenticated" in text
app._toggle_url()
assert app._auth_url_visible is False
text = detail.update.call_args.args[0]
assert "https://auth.example.com/oauth" not in text
def test_toggle_url_noop_without_url(self) -> None:
app = _make_app()
app._auth_url = None
app._toggle_url()
assert app._auth_url_visible is False
class TestDetailText:
def test_without_url_visible(self) -> None:
app = cast(Any, _make_app())
app._auth_url = "https://auth.example.com/oauth"
app._auth_url_visible = False
detail = MagicMock()
app.query_one = lambda sel, *a, **kw: detail
app._update_detail_text()
text = detail.update.call_args.args[0]
assert "Once authenticated, press R to refresh" in text
assert "https://auth.example.com" not in text
def test_with_url_visible(self) -> None:
app = cast(Any, _make_app())
app._auth_url = "https://auth.example.com/oauth"
app._auth_url_visible = True
detail = MagicMock()
app.query_one = lambda sel, *a, **kw: detail
app._update_detail_text()
text = detail.update.call_args.args[0]
assert "https://auth.example.com/oauth" in text
assert "Once authenticated, press R to refresh" in text
# URL should come before the footer
url_pos = text.index("https://auth.example.com/oauth")
footer_pos = text.index("Once authenticated")
assert url_pos < footer_pos
class TestCloseAndRefresh:
def test_action_close_posts_message(self) -> None:
app = _make_app()
app.post_message = MagicMock()
app.action_close()
msg = app.post_message.call_args.args[0]
assert isinstance(msg, ConnectorAuthApp.ConnectorAuthClosed)
assert msg.refreshed is False
def test_on_connector_refreshed_with_tools_posts_closed(self) -> None:
app = _make_app()
app.post_message = MagicMock()
app._on_connector_refreshed(3)
msg = app.post_message.call_args.args[0]
assert isinstance(msg, ConnectorAuthApp.ConnectorAuthClosed)
assert msg.refreshed is True
assert msg.connector_name == "slack"
assert "3 tools" in (app._status_message or "")
def test_on_connector_refreshed_without_tools_stays_on_page(self) -> None:
app = _make_app()
app.post_message = MagicMock()
app.query_one = MagicMock()
app._on_connector_refreshed(0)
app.post_message.assert_not_called()
assert app._status_message is not None
assert "pending" in app._status_message
@pytest.mark.asyncio
async def test_action_refresh_dispatches_worker(self) -> None:
app = _make_app()
app.run_worker = MagicMock()
app.query_one = MagicMock()
await app.action_refresh()
assert app._status_message == "Refreshing connector..."
app.run_worker.assert_called_once()
_, kwargs = app.run_worker.call_args
assert kwargs["group"] == "connector_refresh"
class TestOptionSelection:
def test_auth_open_dispatches(self) -> None:
app = _make_app()
app._auth_url = "https://auth.example.com"
app.query_one = MagicMock()
event = MagicMock()
event.option.id = _AuthOptionId.OPEN
with patch("vibe.cli.textual_ui.widgets.connector_auth_app.webbrowser") as wb:
app.on_option_list_option_selected(event)
wb.open.assert_called_once()
def test_auth_copy_dispatches(self) -> None:
app = cast(Any, _make_app())
app._auth_url = "https://auth.example.com"
event = MagicMock()
event.option.id = _AuthOptionId.COPY
with (
patch.object(
type(app), "app", new_callable=lambda: property(lambda s: MagicMock())
),
patch(
"vibe.cli.textual_ui.widgets.connector_auth_app.copy_text_to_clipboard"
) as copy_fn,
):
app.on_option_list_option_selected(event)
copy_fn.assert_called_once()
def test_auth_show_dispatches(self) -> None:
app = cast(Any, _make_app())
app._auth_url = "https://auth.example.com"
app.query_one = MagicMock()
event = MagicMock()
event.option.id = _AuthOptionId.SHOW
app.on_option_list_option_selected(event)
assert app._auth_url_visible is True
def test_unknown_option_is_noop(self) -> None:
app = _make_app()
event = MagicMock()
event.option.id = "something:else"
# Should not raise
app.on_option_list_option_selected(event)
class TestWorkerStateChanged:
def test_auth_url_worker_dispatches(self) -> None:
app = _make_app()
app.query_one = MagicMock()
worker = MagicMock()
worker.group = "auth_url"
worker.is_finished = True
worker.result = "https://auth.example.com"
event = MagicMock()
event.worker = worker
app.on_worker_state_changed(event)
assert app._auth_url == "https://auth.example.com"
def test_connector_refresh_worker_with_tools_posts_closed(self) -> None:
app = _make_app()
app.post_message = MagicMock()
worker = MagicMock()
worker.group = "connector_refresh"
worker.is_finished = True
worker.result = 5
event = MagicMock()
event.worker = worker
app.on_worker_state_changed(event)
msg = app.post_message.call_args.args[0]
assert isinstance(msg, ConnectorAuthApp.ConnectorAuthClosed)
assert msg.refreshed is True
def test_connector_refresh_worker_without_tools_stays(self) -> None:
app = _make_app()
app.post_message = MagicMock()
app.query_one = MagicMock()
worker = MagicMock()
worker.group = "connector_refresh"
worker.is_finished = True
worker.result = 0
event = MagicMock()
event.worker = worker
app.on_worker_state_changed(event)
app.post_message.assert_not_called()
assert "pending" in (app._status_message or "")
def test_unrelated_worker_is_ignored(self) -> None:
app = _make_app()
worker = MagicMock()
worker.group = "other"
worker.is_finished = True
event = MagicMock()
event.worker = worker
# Should not raise
app.on_worker_state_changed(event)

View file

@ -8,7 +8,10 @@ import pytest
from tests.stubs.fake_connector_registry import FakeConnectorRegistry from tests.stubs.fake_connector_registry import FakeConnectorRegistry
from vibe.cli.textual_ui.widgets.mcp_app import ( from vibe.cli.textual_ui.widgets.mcp_app import (
_LIST_VIEW_HELP_AUTH,
_LIST_VIEW_HELP_TOOLS,
MCPApp, MCPApp,
MCPSourceKind,
_sort_connector_names_for_menu, _sort_connector_names_for_menu,
collect_mcp_tool_index, collect_mcp_tool_index,
) )
@ -258,3 +261,115 @@ class TestConnectorMenuOrdering:
) )
assert ordered == ["alpha", "Beta", "Zeta"] assert ordered == ["alpha", "Beta", "Zeta"]
class TestHelpBarChanges:
"""The help bar should show 'Enter Authenticate' for disconnected connectors."""
def _make_app_with_connectors(self) -> MCPApp:
registry = FakeConnectorRegistry(
connectors={
"gmail": [RemoteTool(name="search", description="Search")],
"slack": [],
}
)
mgr = _make_tool_manager({})
return MCPApp(
mcp_servers=[MCPStdio(name="srv", transport="stdio", command="cmd")],
tool_manager=mgr,
connector_registry=registry,
)
def test_help_shows_show_tools_for_server(self) -> None:
app = self._make_app_with_connectors()
option = MagicMock()
option.id = "server:srv"
assert app._list_help_for_option(option) == _LIST_VIEW_HELP_TOOLS
def test_help_shows_show_tools_for_connected_connector(self) -> None:
app = self._make_app_with_connectors()
option = MagicMock()
option.id = "connector:gmail"
assert app._list_help_for_option(option) == _LIST_VIEW_HELP_TOOLS
def test_help_shows_authenticate_for_disconnected_connector(self) -> None:
app = self._make_app_with_connectors()
option = MagicMock()
option.id = "connector:slack"
assert app._list_help_for_option(option) == _LIST_VIEW_HELP_AUTH
def test_help_defaults_to_tools_for_unknown_option(self) -> None:
app = self._make_app_with_connectors()
option = MagicMock()
option.id = ""
assert app._list_help_for_option(option) == _LIST_VIEW_HELP_TOOLS
def test_help_shows_tools_without_registry(self) -> None:
mgr = _make_tool_manager({})
app = MCPApp(mcp_servers=[], tool_manager=mgr)
option = MagicMock()
option.id = "connector:slack"
assert app._list_help_for_option(option) == _LIST_VIEW_HELP_TOOLS
class TestConnectorAuthRequested:
"""Clicking a disconnected connector posts ConnectorAuthRequested."""
def test_disconnected_connector_posts_auth_requested(self) -> None:
registry = FakeConnectorRegistry(connectors={"slack": []})
mgr = _make_tool_manager({})
app = MCPApp(mcp_servers=[], tool_manager=mgr, connector_registry=registry)
app.query_one = MagicMock()
app.post_message = MagicMock()
option_list = MagicMock()
app._show_detail_view(
"slack", option_list, app._index, kind=MCPSourceKind.CONNECTOR
)
app.post_message.assert_called_once()
msg = app.post_message.call_args.args[0]
assert isinstance(msg, MCPApp.ConnectorAuthRequested)
assert msg.connector_name == "slack"
assert msg.connector_registry is registry
assert msg.tool_manager is mgr
def test_connected_connector_with_no_indexed_tools_shows_message(self) -> None:
registry = MagicMock()
registry.get_connector_names.return_value = ["slack"]
registry.is_connected.return_value = True
mgr = _make_tool_manager({})
app = MCPApp(mcp_servers=[], tool_manager=mgr, connector_registry=registry)
app.query_one = MagicMock()
app.post_message = MagicMock()
option_list = MagicMock()
app._show_detail_view(
"slack", option_list, app._index, kind=MCPSourceKind.CONNECTOR
)
app.post_message.assert_not_called()
option_list.add_option.assert_called_once()
assert "No tools discovered" in str(
option_list.add_option.call_args.args[0].prompt
)
def test_server_with_no_tools_shows_message(self) -> None:
mgr = _make_tool_manager({})
app = MCPApp(
mcp_servers=[MCPStdio(name="srv", transport="stdio", command="cmd")],
tool_manager=mgr,
)
app.query_one = MagicMock()
app.post_message = MagicMock()
option_list = MagicMock()
app._show_detail_view("srv", option_list, app._index, kind=MCPSourceKind.SERVER)
# Should NOT post ConnectorAuthRequested for servers
app.post_message.assert_not_called()
# Should add a "no tools" option instead
option_list.add_option.assert_called_once()
assert "No tools discovered" in str(
option_list.add_option.call_args.args[0].prompt
)

View file

@ -0,0 +1,124 @@
from __future__ import annotations
from collections.abc import Callable
from dataclasses import FrozenInstanceError
from typing import Any, get_args
import pytest
from vibe.core.config import (
AppendToList,
DeleteField,
PatchOp,
RemoveFromList,
SetField,
)
def test_patch_op_union_contains_all_operations() -> None:
assert get_args(PatchOp) == (SetField, AppendToList, RemoveFromList, DeleteField)
def test_set_field_accepts_top_level_key() -> None:
op = SetField("active_model", "devstral-small")
assert op.key == "active_model"
assert op.value == "devstral-small"
def test_set_field_accepts_nested_key() -> None:
op = SetField("models.providers", {"mistral": {"region": "eu"}})
assert op.key == "models.providers"
def test_append_to_list_accepts_nested_key() -> None:
op = AppendToList("tools.disabled_tools", ("bash", "python"))
assert op.key == "tools.disabled_tools"
assert op.items == ("bash", "python")
def test_remove_from_list_accepts_nested_key() -> None:
op = RemoveFromList("models.available_models", ("codestral-latest",))
assert op.key == "models.available_models"
assert op.values == ("codestral-latest",)
def test_delete_field_accepts_nested_key() -> None:
op = DeleteField("tools.deprecated_setting")
assert op.key == "tools.deprecated_setting"
@pytest.mark.parametrize(
"factory",
[
lambda key: SetField(key, "value"),
lambda key: AppendToList(key, ("value",)),
lambda key: RemoveFromList(key, ("value",)),
lambda key: DeleteField(key),
],
)
@pytest.mark.parametrize(
"invalid_key", ["", ".active_model", "active_model.", "tools..bash"]
)
def test_patch_operations_reject_invalid_key_paths(
factory: Callable[[str], object], invalid_key: str
) -> None:
with pytest.raises(ValueError, match="dot-separated path|must not be empty"):
factory(invalid_key)
@pytest.mark.parametrize(
"factory",
[
lambda key: SetField(key, "value"),
lambda key: AppendToList(key, ("value",)),
lambda key: RemoveFromList(key, ("value",)),
lambda key: DeleteField(key),
],
)
def test_patch_operations_reject_non_string_keys(
factory: Callable[[Any], object],
) -> None:
with pytest.raises(TypeError, match="Patch operation key must be a string"):
factory(1)
def test_append_to_list_rejects_non_tuple_items() -> None:
bad_items: Any = ["bash"]
with pytest.raises(TypeError, match="AppendToList.items must be a tuple"):
AppendToList("tools.disabled_tools", bad_items)
def test_remove_from_list_rejects_non_tuple_values() -> None:
bad_values: Any = ["bash"]
with pytest.raises(TypeError, match="RemoveFromList.values must be a tuple"):
RemoveFromList("tools.disabled_tools", bad_values)
def test_patch_operations_are_frozen() -> None:
op = SetField("active_model", "devstral-small")
with pytest.raises(FrozenInstanceError):
op.__setattr__("key", "models.active_model")
def test_scenario_mini_vibe_patch_operations() -> None:
operations: list[PatchOp] = [
SetField("active_model", "devstral-small"),
AppendToList("tools.disabled_tools", ("bash",)),
RemoveFromList("models.available_models", ("codestral-latest",)),
DeleteField("tools.deprecated_setting"),
]
assert operations == [
SetField("active_model", "devstral-small"),
AppendToList("tools.disabled_tools", ("bash",)),
RemoveFromList("models.available_models", ("codestral-latest",)),
DeleteField("tools.deprecated_setting"),
]

View file

@ -293,6 +293,241 @@ class TestMigrateLeavesFindInBashAllowlist:
assert "tools" not in result assert "tools" not in result
class TestMigrateMistralVibeCliLatestDefaults:
def test_updates_alias_temperature_and_thinking_for_default_model(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("VIBE_HOME", str(tmp_path))
config_file = tmp_path / "config.toml"
data = {
"models": [
{
"name": "mistral-vibe-cli-latest",
"provider": "mistral",
"alias": "devstral-2",
"temperature": 0.2,
"thinking": "off",
}
]
}
with config_file.open("wb") as f:
tomli_w.dump(data, f)
reset_harness_files_manager()
init_harness_files_manager("user")
VibeConfig._migrate()
with config_file.open("rb") as f:
result = tomllib.load(f)
assert result["models"][0]["alias"] == "mistral-medium-3.5"
assert result["models"][0]["temperature"] == 1.0
assert result["models"][0]["input_price"] == 1.5
assert result["models"][0]["output_price"] == 7.5
assert result["models"][0]["thinking"] == "high"
def test_updates_active_model_when_devstral_2(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("VIBE_HOME", str(tmp_path))
config_file = tmp_path / "config.toml"
data = {
"active_model": "devstral-2",
"models": [
{
"name": "mistral-vibe-cli-latest",
"provider": "mistral",
"alias": "devstral-2",
}
],
}
with config_file.open("wb") as f:
tomli_w.dump(data, f)
reset_harness_files_manager()
init_harness_files_manager("user")
VibeConfig._migrate()
with config_file.open("rb") as f:
result = tomllib.load(f)
assert result["active_model"] == "mistral-medium-3.5"
def test_adds_temperature_and_thinking_when_missing(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("VIBE_HOME", str(tmp_path))
config_file = tmp_path / "config.toml"
data = {
"models": [
{
"name": "mistral-vibe-cli-latest",
"provider": "mistral",
"alias": "devstral-2",
}
]
}
with config_file.open("wb") as f:
tomli_w.dump(data, f)
reset_harness_files_manager()
init_harness_files_manager("user")
VibeConfig._migrate()
with config_file.open("rb") as f:
result = tomllib.load(f)
assert result["models"][0]["alias"] == "mistral-medium-3.5"
assert result["models"][0]["temperature"] == 1.0
assert result["models"][0]["input_price"] == 1.5
assert result["models"][0]["output_price"] == 7.5
assert result["models"][0]["thinking"] == "high"
def test_skips_model_with_customized_alias(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("VIBE_HOME", str(tmp_path))
config_file = tmp_path / "config.toml"
data = {
"models": [
{
"name": "mistral-vibe-cli-latest",
"provider": "mistral",
"alias": "my-custom-alias",
"temperature": 0.2,
"thinking": "off",
}
]
}
with config_file.open("wb") as f:
tomli_w.dump(data, f)
reset_harness_files_manager()
init_harness_files_manager("user")
VibeConfig._migrate()
with config_file.open("rb") as f:
result = tomllib.load(f)
assert result["models"][0]["alias"] == "my-custom-alias"
assert result["models"][0]["temperature"] == 0.2
assert result["models"][0]["thinking"] == "off"
def test_does_not_touch_other_models(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("VIBE_HOME", str(tmp_path))
config_file = tmp_path / "config.toml"
data = {
"models": [
{
"name": "mistral-vibe-cli-latest",
"provider": "mistral",
"alias": "devstral-2",
},
{
"name": "other-model",
"provider": "mistral",
"alias": "devstral-2-clone",
"temperature": 0.5,
"thinking": "low",
},
]
}
with config_file.open("wb") as f:
tomli_w.dump(data, f)
reset_harness_files_manager()
init_harness_files_manager("user")
VibeConfig._migrate()
with config_file.open("rb") as f:
result = tomllib.load(f)
assert result["models"][1]["alias"] == "devstral-2-clone"
assert result["models"][1]["temperature"] == 0.5
assert result["models"][1]["thinking"] == "low"
def test_noop_when_no_models_section(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("VIBE_HOME", str(tmp_path))
config_file = tmp_path / "config.toml"
data = {"theme": "dark"}
with config_file.open("wb") as f:
tomli_w.dump(data, f)
reset_harness_files_manager()
init_harness_files_manager("user")
VibeConfig._migrate()
with config_file.open("rb") as f:
result = tomllib.load(f)
assert result == {"theme": "dark"}
def test_idempotent_when_already_migrated(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("VIBE_HOME", str(tmp_path))
config_file = tmp_path / "config.toml"
data = {
"active_model": "mistral-medium-3.5",
"models": [
{
"name": "mistral-vibe-cli-latest",
"provider": "mistral",
"alias": "mistral-medium-3.5",
"temperature": 1.0,
"input_price": 1.5,
"output_price": 7.5,
"thinking": "high",
}
],
}
with config_file.open("wb") as f:
tomli_w.dump(data, f)
reset_harness_files_manager()
init_harness_files_manager("user")
VibeConfig._migrate()
VibeConfig._migrate()
with config_file.open("rb") as f:
result = tomllib.load(f)
assert result["active_model"] == "mistral-medium-3.5"
assert result["models"][0]["alias"] == "mistral-medium-3.5"
assert result["models"][0]["temperature"] == 1.0
assert result["models"][0]["input_price"] == 1.5
assert result["models"][0]["output_price"] == 7.5
assert result["models"][0]["thinking"] == "high"
def test_migrates_model_and_active_model_together(
self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.setenv("VIBE_HOME", str(tmp_path))
config_file = tmp_path / "config.toml"
data = {
"active_model": "devstral-2",
"models": [
{
"name": "mistral-vibe-cli-latest",
"provider": "mistral",
"alias": "devstral-2",
}
],
}
with config_file.open("wb") as f:
tomli_w.dump(data, f)
reset_harness_files_manager()
init_harness_files_manager("user")
VibeConfig._migrate()
with config_file.open("rb") as f:
result = tomllib.load(f)
assert result["active_model"] == "mistral-medium-3.5"
assert result["models"][0]["alias"] == "mistral-medium-3.5"
assert result["models"][0]["temperature"] == 1.0
assert result["models"][0]["input_price"] == 1.5
assert result["models"][0]["output_price"] == 7.5
assert result["models"][0]["thinking"] == "high"
class TestAutoCompactThresholdFallback: class TestAutoCompactThresholdFallback:
def test_model_without_explicit_threshold_inherits_global(self) -> None: def test_model_without_explicit_threshold_inherits_global(self) -> None:
model = ModelConfig(name="m", provider="p", alias="m") model = ModelConfig(name="m", provider="p", alias="m")

View file

@ -357,6 +357,7 @@ class TestTeleportServiceExecute:
github_pending = MagicMock() github_pending = MagicMock()
github_pending.connected = False github_pending.connected = False
github_pending.oauth_url = "https://github.com/login/oauth" github_pending.oauth_url = "https://github.com/login/oauth"
github_pending.error = None
github_pending.status = GitHubStatus.WAITING_FOR_OAUTH github_pending.status = GitHubStatus.WAITING_FOR_OAUTH
github_connected = MagicMock() github_connected = MagicMock()

View file

@ -0,0 +1,206 @@
<svg class="rich-terminal" viewBox="0 0 1482 928.4" xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
font-style: normal;
font-weight: 400;
}
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Bold"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
font-style: bold;
font-weight: 700;
}
.terminal-matrix {
font-family: Fira Code, monospace;
font-size: 20px;
line-height: 24.4px;
font-variant-east-asian: full-width;
}
.terminal-title {
font-size: 18px;
font-weight: bold;
font-family: arial;
}
.terminal-r1 { fill: #c5c8c6 }
.terminal-r2 { fill: #ff8205;font-weight: bold }
.terminal-r3 { fill: #68a0b3 }
.terminal-r4 { fill: #ff8205 }
.terminal-r5 { fill: #9a9b99 }
.terminal-r6 { fill: #608ab1;font-weight: bold }
.terminal-r7 { fill: #c5c8c6;font-weight: bold }
.terminal-r8 { fill: #9cafbd;font-weight: bold }
.terminal-r9 { fill: #98a84b;font-weight: bold }
.terminal-r10 { fill: #868887 }
</style>
<defs>
<clipPath id="terminal-clip-terminal">
<rect x="0" y="0" width="1463.0" height="877.4" />
</clipPath>
<clipPath id="terminal-line-0">
<rect x="0" y="1.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-1">
<rect x="0" y="25.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-2">
<rect x="0" y="50.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-3">
<rect x="0" y="74.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-4">
<rect x="0" y="99.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-5">
<rect x="0" y="123.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-6">
<rect x="0" y="147.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-7">
<rect x="0" y="172.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-8">
<rect x="0" y="196.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-9">
<rect x="0" y="221.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-10">
<rect x="0" y="245.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-11">
<rect x="0" y="269.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-12">
<rect x="0" y="294.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-13">
<rect x="0" y="318.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-14">
<rect x="0" y="343.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-15">
<rect x="0" y="367.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-16">
<rect x="0" y="391.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-17">
<rect x="0" y="416.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-18">
<rect x="0" y="440.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-19">
<rect x="0" y="465.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-20">
<rect x="0" y="489.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-21">
<rect x="0" y="513.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-22">
<rect x="0" y="538.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-23">
<rect x="0" y="562.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-24">
<rect x="0" y="587.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-25">
<rect x="0" y="611.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-26">
<rect x="0" y="635.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-27">
<rect x="0" y="660.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-28">
<rect x="0" y="684.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-29">
<rect x="0" y="709.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-30">
<rect x="0" y="733.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-31">
<rect x="0" y="757.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-32">
<rect x="0" y="782.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-33">
<rect x="0" y="806.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-34">
<rect x="0" y="831.1" width="1464" height="24.65"/>
</clipPath>
</defs>
<rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="926.4" rx="8"/><text class="terminal-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">SnapshotTestAppConnectorsMixedState</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
<circle cx="44" cy="0" r="7" fill="#28c840"/>
</g>
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<rect fill="#608ab1" x="36.6" y="733.5" width="85.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="122" y="733.5" width="158.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="280.6" y="733.5" width="122" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="402.6" y="733.5" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="427" y="733.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="439.2" y="733.5" width="122" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="561.2" y="733.5" width="866.2" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-matrix">
<text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)">
</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
</text><text class="terminal-r1" x="1464" y="93.2" textLength="12.2" clip-path="url(#terminal-line-3)">
</text><text class="terminal-r1" x="1464" y="117.6" textLength="12.2" clip-path="url(#terminal-line-4)">
</text><text class="terminal-r1" x="1464" y="142" textLength="12.2" clip-path="url(#terminal-line-5)">
</text><text class="terminal-r1" x="1464" y="166.4" textLength="12.2" clip-path="url(#terminal-line-6)">
</text><text class="terminal-r1" x="1464" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)">
</text><text class="terminal-r1" x="1464" y="215.2" textLength="12.2" clip-path="url(#terminal-line-8)">
</text><text class="terminal-r1" x="1464" y="239.6" textLength="12.2" clip-path="url(#terminal-line-9)">
</text><text class="terminal-r1" x="1464" y="264" textLength="12.2" clip-path="url(#terminal-line-10)">
</text><text class="terminal-r1" x="1464" y="288.4" textLength="12.2" clip-path="url(#terminal-line-11)">
</text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)">
</text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)">
</text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)">
</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="0" y="410.4" textLength="134.2" clip-path="url(#terminal-line-16)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="410.4" textLength="146.4" clip-path="url(#terminal-line-16)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="410.4" textLength="122" clip-path="url(#terminal-line-16)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="410.4" textLength="244" clip-path="url(#terminal-line-16)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="410.4" textLength="256.2" clip-path="url(#terminal-line-16)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="0" y="434.8" textLength="134.2" clip-path="url(#terminal-line-17)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="434.8" textLength="597.8" clip-path="url(#terminal-line-17)">1&#160;model&#160;·&#160;3&#160;connectors&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="459.2" textLength="61" clip-path="url(#terminal-line-18)">Type&#160;</text><text class="terminal-r3" x="231.8" y="459.2" textLength="61" clip-path="url(#terminal-line-18)">/help</text><text class="terminal-r1" x="292.8" y="459.2" textLength="256.2" clip-path="url(#terminal-line-18)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r4" x="0" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"></text><text class="terminal-r2" x="24.4" y="532.4" textLength="48.8" clip-path="url(#terminal-line-21)">/mcp</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r5" x="24.4" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"></text><text class="terminal-r1" x="48.8" y="556.8" textLength="256.2" clip-path="url(#terminal-line-22)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r5" x="24.4" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r1" x="48.8" y="581.2" textLength="256.2" clip-path="url(#terminal-line-23)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r5" x="0" y="654.4" textLength="1464" clip-path="url(#terminal-line-26)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r6" x="24.4" y="678.8" textLength="292.8" clip-path="url(#terminal-line-27)">MCP&#160;Servers&#160;&amp;&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r7" x="36.6" y="727.6" textLength="244" clip-path="url(#terminal-line-29)">Workspace&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r7" x="36.6" y="752" textLength="85.4" clip-path="url(#terminal-line-30)">&#160;&#160;alpha</text><text class="terminal-r8" x="122" y="752" textLength="158.6" clip-path="url(#terminal-line-30)">&#160;&#160;[connector]</text><text class="terminal-r8" x="280.6" y="752" textLength="122" clip-path="url(#terminal-line-30)">&#160;&#160;1&#160;tool&#160;&#160;</text><text class="terminal-r9" x="427" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r8" x="439.2" y="752" textLength="122" clip-path="url(#terminal-line-30)">&#160;connected</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">
</text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="36.6" y="776.4" textLength="85.4" clip-path="url(#terminal-line-31)">&#160;&#160;beta&#160;</text><text class="terminal-r10" x="122" y="776.4" textLength="158.6" clip-path="url(#terminal-line-31)">&#160;&#160;[connector]</text><text class="terminal-r10" x="280.6" y="776.4" textLength="122" clip-path="url(#terminal-line-31)">&#160;&#160;no&#160;tools</text><text class="terminal-r10" x="427" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r10" x="439.2" y="776.4" textLength="170.8" clip-path="url(#terminal-line-31)">&#160;not&#160;connected</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)">
</text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="36.6" y="800.8" textLength="85.4" clip-path="url(#terminal-line-32)">&#160;&#160;zeta&#160;</text><text class="terminal-r10" x="122" y="800.8" textLength="158.6" clip-path="url(#terminal-line-32)">&#160;&#160;[connector]</text><text class="terminal-r10" x="280.6" y="800.8" textLength="122" clip-path="url(#terminal-line-32)">&#160;&#160;no&#160;tools</text><text class="terminal-r10" x="427" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r10" x="439.2" y="800.8" textLength="170.8" clip-path="url(#terminal-line-32)">&#160;not&#160;connected</text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)">
</text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="878.4" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)">
</text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)">
</text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

View file

@ -0,0 +1,203 @@
<svg class="rich-terminal" viewBox="0 0 1482 928.4" xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
font-style: normal;
font-weight: 400;
}
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Bold"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
font-style: bold;
font-weight: 700;
}
.terminal-matrix {
font-family: Fira Code, monospace;
font-size: 20px;
line-height: 24.4px;
font-variant-east-asian: full-width;
}
.terminal-title {
font-size: 18px;
font-weight: bold;
font-family: arial;
}
.terminal-r1 { fill: #c5c8c6 }
.terminal-r2 { fill: #ff8205;font-weight: bold }
.terminal-r3 { fill: #68a0b3 }
.terminal-r4 { fill: #ff8205 }
.terminal-r5 { fill: #9a9b99 }
.terminal-r6 { fill: #608ab1;font-weight: bold }
.terminal-r7 { fill: #c5c8c6;font-weight: bold }
</style>
<defs>
<clipPath id="terminal-clip-terminal">
<rect x="0" y="0" width="1463.0" height="877.4" />
</clipPath>
<clipPath id="terminal-line-0">
<rect x="0" y="1.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-1">
<rect x="0" y="25.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-2">
<rect x="0" y="50.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-3">
<rect x="0" y="74.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-4">
<rect x="0" y="99.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-5">
<rect x="0" y="123.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-6">
<rect x="0" y="147.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-7">
<rect x="0" y="172.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-8">
<rect x="0" y="196.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-9">
<rect x="0" y="221.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-10">
<rect x="0" y="245.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-11">
<rect x="0" y="269.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-12">
<rect x="0" y="294.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-13">
<rect x="0" y="318.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-14">
<rect x="0" y="343.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-15">
<rect x="0" y="367.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-16">
<rect x="0" y="391.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-17">
<rect x="0" y="416.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-18">
<rect x="0" y="440.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-19">
<rect x="0" y="465.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-20">
<rect x="0" y="489.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-21">
<rect x="0" y="513.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-22">
<rect x="0" y="538.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-23">
<rect x="0" y="562.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-24">
<rect x="0" y="587.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-25">
<rect x="0" y="611.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-26">
<rect x="0" y="635.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-27">
<rect x="0" y="660.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-28">
<rect x="0" y="684.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-29">
<rect x="0" y="709.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-30">
<rect x="0" y="733.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-31">
<rect x="0" y="757.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-32">
<rect x="0" y="782.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-33">
<rect x="0" y="806.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-34">
<rect x="0" y="831.1" width="1464" height="24.65"/>
</clipPath>
</defs>
<rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="926.4" rx="8"/><text class="terminal-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">SnapshotTestAppConnectorsMixedState</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
<circle cx="44" cy="0" r="7" fill="#28c840"/>
</g>
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<rect fill="#608ab1" x="36.6" y="660.3" width="512.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="549" y="660.3" width="878.4" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-matrix">
<text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)">
</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
</text><text class="terminal-r1" x="1464" y="93.2" textLength="12.2" clip-path="url(#terminal-line-3)">
</text><text class="terminal-r1" x="1464" y="117.6" textLength="12.2" clip-path="url(#terminal-line-4)">
</text><text class="terminal-r1" x="1464" y="142" textLength="12.2" clip-path="url(#terminal-line-5)">
</text><text class="terminal-r1" x="1464" y="166.4" textLength="12.2" clip-path="url(#terminal-line-6)">
</text><text class="terminal-r1" x="1464" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)">
</text><text class="terminal-r1" x="1464" y="215.2" textLength="12.2" clip-path="url(#terminal-line-8)">
</text><text class="terminal-r1" x="1464" y="239.6" textLength="12.2" clip-path="url(#terminal-line-9)">
</text><text class="terminal-r1" x="1464" y="264" textLength="12.2" clip-path="url(#terminal-line-10)">
</text><text class="terminal-r1" x="1464" y="288.4" textLength="12.2" clip-path="url(#terminal-line-11)">
</text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)">
</text><text class="terminal-r1" x="0" y="337.2" textLength="134.2" clip-path="url(#terminal-line-13)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="337.2" textLength="146.4" clip-path="url(#terminal-line-13)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="337.2" textLength="122" clip-path="url(#terminal-line-13)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="337.2" textLength="244" clip-path="url(#terminal-line-13)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="337.2" textLength="256.2" clip-path="url(#terminal-line-13)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)">
</text><text class="terminal-r1" x="0" y="361.6" textLength="134.2" clip-path="url(#terminal-line-14)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="361.6" textLength="597.8" clip-path="url(#terminal-line-14)">1&#160;model&#160;·&#160;3&#160;connectors&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)">
</text><text class="terminal-r1" x="0" y="386" textLength="134.2" clip-path="url(#terminal-line-15)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="386" textLength="61" clip-path="url(#terminal-line-15)">Type&#160;</text><text class="terminal-r3" x="231.8" y="386" textLength="61" clip-path="url(#terminal-line-15)">/help</text><text class="terminal-r1" x="292.8" y="386" textLength="256.2" clip-path="url(#terminal-line-15)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r4" x="0" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"></text><text class="terminal-r2" x="24.4" y="459.2" textLength="48.8" clip-path="url(#terminal-line-18)">/mcp</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r5" x="24.4" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"></text><text class="terminal-r1" x="48.8" y="483.6" textLength="256.2" clip-path="url(#terminal-line-19)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r5" x="0" y="556.8" textLength="1464" clip-path="url(#terminal-line-22)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r5" x="0" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r6" x="24.4" y="581.2" textLength="183" clip-path="url(#terminal-line-23)">Connector:&#160;beta</text><text class="terminal-r5" x="1451.8" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r5" x="0" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r5" x="1451.8" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-r5" x="0" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r1" x="36.6" y="630" textLength="463.6" clip-path="url(#terminal-line-25)">This&#160;connector&#160;requires&#160;authentication</text><text class="terminal-r5" x="1451.8" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r5" x="1451.8" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r7" x="36.6" y="678.8" textLength="512.4" clip-path="url(#terminal-line-27)">&#160;&#160;Press&#160;enter&#160;to&#160;open&#160;auth&#160;in&#160;your&#160;browser</text><text class="terminal-r5" x="1451.8" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="36.6" y="703.2" textLength="280.6" clip-path="url(#terminal-line-28)">&#160;&#160;Copy&#160;URL&#160;to&#160;clipboard</text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="36.6" y="727.6" textLength="280.6" clip-path="url(#terminal-line-29)">&#160;&#160;Manually&#160;show&#160;the&#160;URL</text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">
</text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="24.4" y="776.4" textLength="463.6" clip-path="url(#terminal-line-31)">Once&#160;authenticated,&#160;press&#160;R&#160;to&#160;refresh</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)">
</text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)">
</text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="170.8" clip-path="url(#terminal-line-33)">Backspace&#160;Back</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)">
</text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)">
</text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -0,0 +1,203 @@
<svg class="rich-terminal" viewBox="0 0 1482 928.4" xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
font-style: normal;
font-weight: 400;
}
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Bold"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
font-style: bold;
font-weight: 700;
}
.terminal-matrix {
font-family: Fira Code, monospace;
font-size: 20px;
line-height: 24.4px;
font-variant-east-asian: full-width;
}
.terminal-title {
font-size: 18px;
font-weight: bold;
font-family: arial;
}
.terminal-r1 { fill: #c5c8c6 }
.terminal-r2 { fill: #ff8205;font-weight: bold }
.terminal-r3 { fill: #68a0b3 }
.terminal-r4 { fill: #ff8205 }
.terminal-r5 { fill: #9a9b99 }
.terminal-r6 { fill: #608ab1;font-weight: bold }
.terminal-r7 { fill: #c5c8c6;font-weight: bold }
</style>
<defs>
<clipPath id="terminal-clip-terminal">
<rect x="0" y="0" width="1463.0" height="877.4" />
</clipPath>
<clipPath id="terminal-line-0">
<rect x="0" y="1.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-1">
<rect x="0" y="25.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-2">
<rect x="0" y="50.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-3">
<rect x="0" y="74.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-4">
<rect x="0" y="99.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-5">
<rect x="0" y="123.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-6">
<rect x="0" y="147.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-7">
<rect x="0" y="172.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-8">
<rect x="0" y="196.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-9">
<rect x="0" y="221.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-10">
<rect x="0" y="245.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-11">
<rect x="0" y="269.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-12">
<rect x="0" y="294.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-13">
<rect x="0" y="318.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-14">
<rect x="0" y="343.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-15">
<rect x="0" y="367.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-16">
<rect x="0" y="391.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-17">
<rect x="0" y="416.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-18">
<rect x="0" y="440.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-19">
<rect x="0" y="465.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-20">
<rect x="0" y="489.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-21">
<rect x="0" y="513.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-22">
<rect x="0" y="538.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-23">
<rect x="0" y="562.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-24">
<rect x="0" y="587.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-25">
<rect x="0" y="611.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-26">
<rect x="0" y="635.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-27">
<rect x="0" y="660.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-28">
<rect x="0" y="684.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-29">
<rect x="0" y="709.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-30">
<rect x="0" y="733.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-31">
<rect x="0" y="757.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-32">
<rect x="0" y="782.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-33">
<rect x="0" y="806.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-34">
<rect x="0" y="831.1" width="1464" height="24.65"/>
</clipPath>
</defs>
<rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="926.4" rx="8"/><text class="terminal-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">SnapshotTestAppConnectorsMixedState</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
<circle cx="44" cy="0" r="7" fill="#28c840"/>
</g>
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<rect fill="#608ab1" x="36.6" y="660.3" width="280.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="317.2" y="660.3" width="1110.2" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-matrix">
<text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)">
</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
</text><text class="terminal-r1" x="1464" y="93.2" textLength="12.2" clip-path="url(#terminal-line-3)">
</text><text class="terminal-r1" x="1464" y="117.6" textLength="12.2" clip-path="url(#terminal-line-4)">
</text><text class="terminal-r1" x="1464" y="142" textLength="12.2" clip-path="url(#terminal-line-5)">
</text><text class="terminal-r1" x="1464" y="166.4" textLength="12.2" clip-path="url(#terminal-line-6)">
</text><text class="terminal-r1" x="1464" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)">
</text><text class="terminal-r1" x="1464" y="215.2" textLength="12.2" clip-path="url(#terminal-line-8)">
</text><text class="terminal-r1" x="1464" y="239.6" textLength="12.2" clip-path="url(#terminal-line-9)">
</text><text class="terminal-r1" x="1464" y="264" textLength="12.2" clip-path="url(#terminal-line-10)">
</text><text class="terminal-r1" x="0" y="288.4" textLength="134.2" clip-path="url(#terminal-line-11)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="288.4" textLength="146.4" clip-path="url(#terminal-line-11)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="288.4" textLength="122" clip-path="url(#terminal-line-11)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="288.4" textLength="244" clip-path="url(#terminal-line-11)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="288.4" textLength="256.2" clip-path="url(#terminal-line-11)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="288.4" textLength="12.2" clip-path="url(#terminal-line-11)">
</text><text class="terminal-r1" x="0" y="312.8" textLength="134.2" clip-path="url(#terminal-line-12)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="312.8" textLength="597.8" clip-path="url(#terminal-line-12)">1&#160;model&#160;·&#160;3&#160;connectors&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)">
</text><text class="terminal-r1" x="0" y="337.2" textLength="134.2" clip-path="url(#terminal-line-13)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="337.2" textLength="61" clip-path="url(#terminal-line-13)">Type&#160;</text><text class="terminal-r3" x="231.8" y="337.2" textLength="61" clip-path="url(#terminal-line-13)">/help</text><text class="terminal-r1" x="292.8" y="337.2" textLength="256.2" clip-path="url(#terminal-line-13)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)">
</text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)">
</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r4" x="0" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"></text><text class="terminal-r2" x="24.4" y="410.4" textLength="48.8" clip-path="url(#terminal-line-16)">/mcp</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r5" x="24.4" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"></text><text class="terminal-r1" x="48.8" y="434.8" textLength="256.2" clip-path="url(#terminal-line-17)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r5" x="0" y="508" textLength="1464" clip-path="url(#terminal-line-20)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r5" x="0" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"></text><text class="terminal-r6" x="24.4" y="532.4" textLength="183" clip-path="url(#terminal-line-21)">Connector:&#160;beta</text><text class="terminal-r5" x="1451.8" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"></text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r5" x="0" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"></text><text class="terminal-r5" x="1451.8" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"></text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r5" x="0" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r1" x="36.6" y="581.2" textLength="463.6" clip-path="url(#terminal-line-23)">This&#160;connector&#160;requires&#160;authentication</text><text class="terminal-r5" x="1451.8" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r5" x="0" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r5" x="1451.8" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-r5" x="0" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r1" x="36.6" y="630" textLength="512.4" clip-path="url(#terminal-line-25)">&#160;&#160;Press&#160;enter&#160;to&#160;open&#160;auth&#160;in&#160;your&#160;browser</text><text class="terminal-r5" x="1451.8" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r1" x="36.6" y="654.4" textLength="280.6" clip-path="url(#terminal-line-26)">&#160;&#160;Copy&#160;URL&#160;to&#160;clipboard</text><text class="terminal-r5" x="1451.8" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r7" x="36.6" y="678.8" textLength="280.6" clip-path="url(#terminal-line-27)">&#160;&#160;Manually&#160;show&#160;the&#160;URL</text><text class="terminal-r5" x="1451.8" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="24.4" y="727.6" textLength="414.8" clip-path="url(#terminal-line-29)">https://fake-auth.example.com/beta</text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">
</text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="24.4" y="776.4" textLength="463.6" clip-path="url(#terminal-line-31)">Once&#160;authenticated,&#160;press&#160;R&#160;to&#160;refresh</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)">
</text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)">
</text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="170.8" clip-path="url(#terminal-line-33)">Backspace&#160;Back</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)">
</text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)">
</text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -162,7 +162,7 @@
</g> </g>
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)"> <g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<rect fill="#608ab1" x="36.6" y="733.5" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="183" y="733.5" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="292.8" y="733.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="390.4" y="733.5" width="1037" height="24.65" shape-rendering="crispEdges"/> <rect fill="#608ab1" x="36.6" y="757.9" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="183" y="757.9" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="292.8" y="757.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="390.4" y="757.9" width="1037" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-matrix"> <g class="terminal-matrix">
<text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)"> <text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)"> </text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)">
@ -181,22 +181,22 @@
</text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)"> </text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)">
</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)"> </text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="0" y="434.8" textLength="134.2" clip-path="url(#terminal-line-17)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="434.8" textLength="146.4" clip-path="url(#terminal-line-17)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="434.8" textLength="122" clip-path="url(#terminal-line-17)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="434.8" textLength="244" clip-path="url(#terminal-line-17)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="434.8" textLength="256.2" clip-path="url(#terminal-line-17)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="459.2" textLength="414.8" clip-path="url(#terminal-line-18)">1&#160;model&#160;·&#160;2&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="459.2" textLength="146.4" clip-path="url(#terminal-line-18)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="459.2" textLength="122" clip-path="url(#terminal-line-18)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="459.2" textLength="244" clip-path="url(#terminal-line-18)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="459.2" textLength="256.2" clip-path="url(#terminal-line-18)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="483.6" textLength="61" clip-path="url(#terminal-line-19)">Type&#160;</text><text class="terminal-r3" x="231.8" y="483.6" textLength="61" clip-path="url(#terminal-line-19)">/help</text><text class="terminal-r1" x="292.8" y="483.6" textLength="256.2" clip-path="url(#terminal-line-19)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="483.6" textLength="414.8" clip-path="url(#terminal-line-19)">1&#160;model&#160;·&#160;2&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r1" x="0" y="508" textLength="134.2" clip-path="url(#terminal-line-20)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="508" textLength="61" clip-path="url(#terminal-line-20)">Type&#160;</text><text class="terminal-r3" x="231.8" y="508" textLength="61" clip-path="url(#terminal-line-20)">/help</text><text class="terminal-r1" x="292.8" y="508" textLength="256.2" clip-path="url(#terminal-line-20)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r4" x="0" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"></text><text class="terminal-r2" x="24.4" y="556.8" textLength="183" clip-path="url(#terminal-line-22)">/mcp&#160;filesystem</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r5" x="24.4" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r1" x="48.8" y="581.2" textLength="256.2" clip-path="url(#terminal-line-23)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r4" x="0" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r2" x="24.4" y="581.2" textLength="183" clip-path="url(#terminal-line-23)">/mcp&#160;filesystem</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r5" x="24.4" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r1" x="48.8" y="605.6" textLength="256.2" clip-path="url(#terminal-line-24)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r5" x="0" y="654.4" textLength="1464" clip-path="url(#terminal-line-26)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r6" x="24.4" y="678.8" textLength="134.2" clip-path="url(#terminal-line-27)">MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"> </text><text class="terminal-r5" x="0" y="678.8" textLength="1464" clip-path="url(#terminal-line-27)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"> </text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r6" x="24.4" y="703.2" textLength="134.2" clip-path="url(#terminal-line-28)">MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r7" x="36.6" y="727.6" textLength="207.4" clip-path="url(#terminal-line-29)">Local&#160;MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"> </text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r7" x="36.6" y="752" textLength="146.4" clip-path="url(#terminal-line-30)">&#160;&#160;filesystem</text><text class="terminal-r8" x="183" y="752" textLength="109.8" clip-path="url(#terminal-line-30)">&#160;&#160;[stdio]</text><text class="terminal-r8" x="292.8" y="752" textLength="97.6" clip-path="url(#terminal-line-30)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"> </text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r7" x="36.6" y="752" textLength="207.4" clip-path="url(#terminal-line-30)">Local&#160;MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">
</text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="36.6" y="776.4" textLength="146.4" clip-path="url(#terminal-line-31)">&#160;&#160;search&#160;&#160;&#160;&#160;</text><text class="terminal-r9" x="183" y="776.4" textLength="109.8" clip-path="url(#terminal-line-31)">&#160;&#160;[http]&#160;</text><text class="terminal-r9" x="292.8" y="776.4" textLength="97.6" clip-path="url(#terminal-line-31)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"> </text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r7" x="36.6" y="776.4" textLength="146.4" clip-path="url(#terminal-line-31)">&#160;&#160;filesystem</text><text class="terminal-r8" x="183" y="776.4" textLength="109.8" clip-path="url(#terminal-line-31)">&#160;&#160;[stdio]</text><text class="terminal-r8" x="292.8" y="776.4" textLength="97.6" clip-path="url(#terminal-line-31)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)">
</text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"> </text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="36.6" y="800.8" textLength="146.4" clip-path="url(#terminal-line-32)">&#160;&#160;search&#160;&#160;&#160;&#160;</text><text class="terminal-r9" x="183" y="800.8" textLength="109.8" clip-path="url(#terminal-line-32)">&#160;&#160;[http]&#160;</text><text class="terminal-r9" x="292.8" y="800.8" textLength="97.6" clip-path="url(#terminal-line-32)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)">
</text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="878.4" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"> </text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="878.4" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)">
</text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)"> </text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)">
</text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text> </text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text>

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before After
Before After

View file

@ -162,7 +162,7 @@
</g> </g>
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)"> <g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<rect fill="#608ab1" x="36.6" y="709.1" width="183" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="219.6" y="709.1" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="329.4" y="709.1" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="427" y="709.1" width="1000.4" height="24.65" shape-rendering="crispEdges"/> <rect fill="#608ab1" x="36.6" y="733.5" width="183" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="219.6" y="733.5" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="329.4" y="733.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="427" y="733.5" width="1000.4" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-matrix"> <g class="terminal-matrix">
<text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)"> <text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)"> </text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)">
@ -180,23 +180,23 @@
</text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)"> </text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)">
</text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)"> </text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)">
</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)"> </text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="0" y="410.4" textLength="134.2" clip-path="url(#terminal-line-16)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="410.4" textLength="146.4" clip-path="url(#terminal-line-16)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="410.4" textLength="122" clip-path="url(#terminal-line-16)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="410.4" textLength="244" clip-path="url(#terminal-line-16)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="410.4" textLength="256.2" clip-path="url(#terminal-line-16)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="0" y="434.8" textLength="134.2" clip-path="url(#terminal-line-17)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="434.8" textLength="414.8" clip-path="url(#terminal-line-17)">1&#160;model&#160;·&#160;2&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="0" y="434.8" textLength="134.2" clip-path="url(#terminal-line-17)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="434.8" textLength="146.4" clip-path="url(#terminal-line-17)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="434.8" textLength="122" clip-path="url(#terminal-line-17)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="434.8" textLength="244" clip-path="url(#terminal-line-17)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="434.8" textLength="256.2" clip-path="url(#terminal-line-17)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="459.2" textLength="61" clip-path="url(#terminal-line-18)">Type&#160;</text><text class="terminal-r3" x="231.8" y="459.2" textLength="61" clip-path="url(#terminal-line-18)">/help</text><text class="terminal-r1" x="292.8" y="459.2" textLength="256.2" clip-path="url(#terminal-line-18)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="459.2" textLength="414.8" clip-path="url(#terminal-line-18)">1&#160;model&#160;·&#160;2&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="483.6" textLength="61" clip-path="url(#terminal-line-19)">Type&#160;</text><text class="terminal-r3" x="231.8" y="483.6" textLength="61" clip-path="url(#terminal-line-19)">/help</text><text class="terminal-r1" x="292.8" y="483.6" textLength="256.2" clip-path="url(#terminal-line-19)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r4" x="0" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"></text><text class="terminal-r2" x="24.4" y="532.4" textLength="48.8" clip-path="url(#terminal-line-21)">/mcp</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r5" x="24.4" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"></text><text class="terminal-r1" x="48.8" y="556.8" textLength="256.2" clip-path="url(#terminal-line-22)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r4" x="0" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"></text><text class="terminal-r2" x="24.4" y="556.8" textLength="48.8" clip-path="url(#terminal-line-22)">/mcp</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r5" x="24.4" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r1" x="48.8" y="581.2" textLength="256.2" clip-path="url(#terminal-line-23)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-r5" x="0" y="630" textLength="1464" clip-path="url(#terminal-line-25)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r6" x="24.4" y="654.4" textLength="134.2" clip-path="url(#terminal-line-26)">MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </text><text class="terminal-r5" x="0" y="654.4" textLength="1464" clip-path="url(#terminal-line-26)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r5" x="1451.8" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"> </text><text class="terminal-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r6" x="24.4" y="678.8" textLength="134.2" clip-path="url(#terminal-line-27)">MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r7" x="36.6" y="703.2" textLength="207.4" clip-path="url(#terminal-line-28)">Local&#160;MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"> </text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r7" x="36.6" y="727.6" textLength="183" clip-path="url(#terminal-line-29)">&#160;&#160;filesystem&#160;&#160;&#160;</text><text class="terminal-r8" x="219.6" y="727.6" textLength="109.8" clip-path="url(#terminal-line-29)">&#160;&#160;[stdio]</text><text class="terminal-r8" x="329.4" y="727.6" textLength="97.6" clip-path="url(#terminal-line-29)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"> </text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r7" x="36.6" y="727.6" textLength="207.4" clip-path="url(#terminal-line-29)">Local&#160;MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="36.6" y="752" textLength="183" clip-path="url(#terminal-line-30)">&#160;&#160;broken-server</text><text class="terminal-r9" x="219.6" y="752" textLength="109.8" clip-path="url(#terminal-line-30)">&#160;&#160;[stdio]</text><text class="terminal-r9" x="329.4" y="752" textLength="122" clip-path="url(#terminal-line-30)">&#160;&#160;no&#160;tools</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"> </text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r7" x="36.6" y="752" textLength="183" clip-path="url(#terminal-line-30)">&#160;&#160;filesystem&#160;&#160;&#160;</text><text class="terminal-r8" x="219.6" y="752" textLength="109.8" clip-path="url(#terminal-line-30)">&#160;&#160;[stdio]</text><text class="terminal-r8" x="329.4" y="752" textLength="97.6" clip-path="url(#terminal-line-30)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">
</text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="36.6" y="776.4" textLength="183" clip-path="url(#terminal-line-31)">&#160;&#160;search&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-r9" x="219.6" y="776.4" textLength="109.8" clip-path="url(#terminal-line-31)">&#160;&#160;[http]&#160;</text><text class="terminal-r9" x="329.4" y="776.4" textLength="97.6" clip-path="url(#terminal-line-31)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"> </text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="36.6" y="776.4" textLength="183" clip-path="url(#terminal-line-31)">&#160;&#160;broken-server</text><text class="terminal-r9" x="219.6" y="776.4" textLength="109.8" clip-path="url(#terminal-line-31)">&#160;&#160;[stdio]</text><text class="terminal-r9" x="329.4" y="776.4" textLength="122" clip-path="url(#terminal-line-31)">&#160;&#160;no&#160;tools</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)">
</text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"> </text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="36.6" y="800.8" textLength="183" clip-path="url(#terminal-line-32)">&#160;&#160;search&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-r9" x="219.6" y="800.8" textLength="109.8" clip-path="url(#terminal-line-32)">&#160;&#160;[http]&#160;</text><text class="terminal-r9" x="329.4" y="800.8" textLength="97.6" clip-path="url(#terminal-line-32)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)">
</text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="878.4" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"> </text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="878.4" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)">
</text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)"> </text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)">
</text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text> </text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text>

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before After
Before After

View file

@ -163,7 +163,7 @@
</g> </g>
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)"> <g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<rect fill="#608ab1" x="36.6" y="660.3" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="183" y="660.3" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="292.8" y="660.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="390.4" y="660.3" width="1037" height="24.65" shape-rendering="crispEdges"/> <rect fill="#608ab1" x="36.6" y="684.7" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="183" y="684.7" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="292.8" y="684.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="390.4" y="684.7" width="1037" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-matrix"> <g class="terminal-matrix">
<text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)"> <text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)"> </text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)">
@ -179,25 +179,25 @@
</text><text class="terminal-r1" x="1464" y="288.4" textLength="12.2" clip-path="url(#terminal-line-11)"> </text><text class="terminal-r1" x="1464" y="288.4" textLength="12.2" clip-path="url(#terminal-line-11)">
</text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)"> </text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)">
</text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)"> </text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)">
</text><text class="terminal-r1" x="0" y="361.6" textLength="134.2" clip-path="url(#terminal-line-14)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="361.6" textLength="146.4" clip-path="url(#terminal-line-14)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="361.6" textLength="122" clip-path="url(#terminal-line-14)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="361.6" textLength="244" clip-path="url(#terminal-line-14)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="361.6" textLength="256.2" clip-path="url(#terminal-line-14)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)"> </text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)">
</text><text class="terminal-r1" x="0" y="386" textLength="134.2" clip-path="url(#terminal-line-15)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="386" textLength="585.6" clip-path="url(#terminal-line-15)">1&#160;model&#160;·&#160;2&#160;connectors&#160;·&#160;1&#160;MCP&#160;server&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)"> </text><text class="terminal-r1" x="0" y="386" textLength="134.2" clip-path="url(#terminal-line-15)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="386" textLength="146.4" clip-path="url(#terminal-line-15)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="386" textLength="122" clip-path="url(#terminal-line-15)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="386" textLength="244" clip-path="url(#terminal-line-15)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="386" textLength="256.2" clip-path="url(#terminal-line-15)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="0" y="410.4" textLength="134.2" clip-path="url(#terminal-line-16)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="410.4" textLength="61" clip-path="url(#terminal-line-16)">Type&#160;</text><text class="terminal-r3" x="231.8" y="410.4" textLength="61" clip-path="url(#terminal-line-16)">/help</text><text class="terminal-r1" x="292.8" y="410.4" textLength="256.2" clip-path="url(#terminal-line-16)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="0" y="410.4" textLength="134.2" clip-path="url(#terminal-line-16)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="410.4" textLength="585.6" clip-path="url(#terminal-line-16)">1&#160;model&#160;·&#160;2&#160;connectors&#160;·&#160;1&#160;MCP&#160;server&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="0" y="434.8" textLength="134.2" clip-path="url(#terminal-line-17)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="434.8" textLength="61" clip-path="url(#terminal-line-17)">Type&#160;</text><text class="terminal-r3" x="231.8" y="434.8" textLength="61" clip-path="url(#terminal-line-17)">/help</text><text class="terminal-r1" x="292.8" y="434.8" textLength="256.2" clip-path="url(#terminal-line-17)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r4" x="0" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"></text><text class="terminal-r2" x="24.4" y="483.6" textLength="48.8" clip-path="url(#terminal-line-19)">/mcp</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r5" x="24.4" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"></text><text class="terminal-r1" x="48.8" y="508" textLength="256.2" clip-path="url(#terminal-line-20)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r4" x="0" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"></text><text class="terminal-r2" x="24.4" y="508" textLength="48.8" clip-path="url(#terminal-line-20)">/mcp</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r5" x="24.4" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"></text><text class="terminal-r1" x="48.8" y="532.4" textLength="256.2" clip-path="url(#terminal-line-21)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r5" x="0" y="581.2" textLength="1464" clip-path="url(#terminal-line-23)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r5" x="0" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r6" x="24.4" y="605.6" textLength="292.8" clip-path="url(#terminal-line-24)">MCP&#160;Servers&#160;&amp;&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r5" x="0" y="605.6" textLength="1464" clip-path="url(#terminal-line-24)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-r5" x="0" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r5" x="1451.8" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </text><text class="terminal-r5" x="0" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r6" x="24.4" y="630" textLength="292.8" clip-path="url(#terminal-line-25)">MCP&#160;Servers&#160;&amp;&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r7" x="36.6" y="654.4" textLength="207.4" clip-path="url(#terminal-line-26)">Local&#160;MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </text><text class="terminal-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r5" x="1451.8" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r7" x="36.6" y="678.8" textLength="146.4" clip-path="url(#terminal-line-27)">&#160;&#160;filesystem</text><text class="terminal-r8" x="183" y="678.8" textLength="109.8" clip-path="url(#terminal-line-27)">&#160;&#160;[stdio]</text><text class="terminal-r8" x="292.8" y="678.8" textLength="97.6" clip-path="url(#terminal-line-27)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"> </text><text class="terminal-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r7" x="36.6" y="678.8" textLength="207.4" clip-path="url(#terminal-line-27)">Local&#160;MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"> </text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r7" x="36.6" y="703.2" textLength="146.4" clip-path="url(#terminal-line-28)">&#160;&#160;filesystem</text><text class="terminal-r8" x="183" y="703.2" textLength="109.8" clip-path="url(#terminal-line-28)">&#160;&#160;[stdio]</text><text class="terminal-r8" x="292.8" y="703.2" textLength="97.6" clip-path="url(#terminal-line-28)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r7" x="36.6" y="727.6" textLength="244" clip-path="url(#terminal-line-29)">Workspace&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"> </text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="36.6" y="752" textLength="85.4" clip-path="url(#terminal-line-30)">&#160;&#160;gmail</text><text class="terminal-r9" x="122" y="752" textLength="158.6" clip-path="url(#terminal-line-30)">&#160;&#160;[connector]</text><text class="terminal-r9" x="280.6" y="752" textLength="109.8" clip-path="url(#terminal-line-30)">&#160;&#160;3&#160;tools</text><text class="terminal-r10" x="414.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r9" x="427" y="752" textLength="122" clip-path="url(#terminal-line-30)">&#160;connected</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"> </text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r7" x="36.6" y="752" textLength="244" clip-path="url(#terminal-line-30)">Workspace&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">
</text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="36.6" y="776.4" textLength="85.4" clip-path="url(#terminal-line-31)">&#160;&#160;slack</text><text class="terminal-r9" x="122" y="776.4" textLength="158.6" clip-path="url(#terminal-line-31)">&#160;&#160;[connector]</text><text class="terminal-r9" x="280.6" y="776.4" textLength="109.8" clip-path="url(#terminal-line-31)">&#160;&#160;2&#160;tools</text><text class="terminal-r10" x="414.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r9" x="427" y="776.4" textLength="122" clip-path="url(#terminal-line-31)">&#160;connected</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"> </text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="36.6" y="776.4" textLength="85.4" clip-path="url(#terminal-line-31)">&#160;&#160;gmail</text><text class="terminal-r9" x="122" y="776.4" textLength="158.6" clip-path="url(#terminal-line-31)">&#160;&#160;[connector]</text><text class="terminal-r9" x="280.6" y="776.4" textLength="109.8" clip-path="url(#terminal-line-31)">&#160;&#160;3&#160;tools</text><text class="terminal-r10" x="414.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r9" x="427" y="776.4" textLength="122" clip-path="url(#terminal-line-31)">&#160;connected</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)">
</text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"> </text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="36.6" y="800.8" textLength="85.4" clip-path="url(#terminal-line-32)">&#160;&#160;slack</text><text class="terminal-r9" x="122" y="800.8" textLength="158.6" clip-path="url(#terminal-line-32)">&#160;&#160;[connector]</text><text class="terminal-r9" x="280.6" y="800.8" textLength="109.8" clip-path="url(#terminal-line-32)">&#160;&#160;2&#160;tools</text><text class="terminal-r10" x="414.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r9" x="427" y="800.8" textLength="122" clip-path="url(#terminal-line-32)">&#160;connected</text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)">
</text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="878.4" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"> </text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="878.4" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)">
</text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)"> </text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)">
</text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text> </text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text>

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Before After
Before After

View file

@ -164,7 +164,7 @@
</g> </g>
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)"> <g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<rect fill="#608ab1" x="36.6" y="733.5" width="85.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="122" y="733.5" width="158.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="280.6" y="733.5" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="390.4" y="733.5" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="414.8" y="733.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="427" y="733.5" width="122" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="549" y="733.5" width="878.4" height="24.65" shape-rendering="crispEdges"/> <rect fill="#608ab1" x="36.6" y="757.9" width="85.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="122" y="757.9" width="158.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="280.6" y="757.9" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="390.4" y="757.9" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="414.8" y="757.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="427" y="757.9" width="122" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="549" y="757.9" width="878.4" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-matrix"> <g class="terminal-matrix">
<text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)"> <text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)"> </text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)">
@ -183,22 +183,22 @@
</text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)"> </text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)">
</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)"> </text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="0" y="434.8" textLength="134.2" clip-path="url(#terminal-line-17)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="434.8" textLength="146.4" clip-path="url(#terminal-line-17)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="434.8" textLength="122" clip-path="url(#terminal-line-17)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="434.8" textLength="244" clip-path="url(#terminal-line-17)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="434.8" textLength="256.2" clip-path="url(#terminal-line-17)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="459.2" textLength="597.8" clip-path="url(#terminal-line-18)">1&#160;model&#160;·&#160;2&#160;connectors&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="459.2" textLength="146.4" clip-path="url(#terminal-line-18)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="459.2" textLength="122" clip-path="url(#terminal-line-18)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="459.2" textLength="244" clip-path="url(#terminal-line-18)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="459.2" textLength="256.2" clip-path="url(#terminal-line-18)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="483.6" textLength="61" clip-path="url(#terminal-line-19)">Type&#160;</text><text class="terminal-r3" x="231.8" y="483.6" textLength="61" clip-path="url(#terminal-line-19)">/help</text><text class="terminal-r1" x="292.8" y="483.6" textLength="256.2" clip-path="url(#terminal-line-19)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="483.6" textLength="597.8" clip-path="url(#terminal-line-19)">1&#160;model&#160;·&#160;2&#160;connectors&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r1" x="0" y="508" textLength="134.2" clip-path="url(#terminal-line-20)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="508" textLength="61" clip-path="url(#terminal-line-20)">Type&#160;</text><text class="terminal-r3" x="231.8" y="508" textLength="61" clip-path="url(#terminal-line-20)">/help</text><text class="terminal-r1" x="292.8" y="508" textLength="256.2" clip-path="url(#terminal-line-20)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r4" x="0" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"></text><text class="terminal-r2" x="24.4" y="556.8" textLength="48.8" clip-path="url(#terminal-line-22)">/mcp</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r5" x="24.4" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r1" x="48.8" y="581.2" textLength="256.2" clip-path="url(#terminal-line-23)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r4" x="0" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r2" x="24.4" y="581.2" textLength="48.8" clip-path="url(#terminal-line-23)">/mcp</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r5" x="24.4" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r1" x="48.8" y="605.6" textLength="256.2" clip-path="url(#terminal-line-24)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r5" x="0" y="654.4" textLength="1464" clip-path="url(#terminal-line-26)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r6" x="24.4" y="678.8" textLength="292.8" clip-path="url(#terminal-line-27)">MCP&#160;Servers&#160;&amp;&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"> </text><text class="terminal-r5" x="0" y="678.8" textLength="1464" clip-path="url(#terminal-line-27)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"> </text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r6" x="24.4" y="703.2" textLength="292.8" clip-path="url(#terminal-line-28)">MCP&#160;Servers&#160;&amp;&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r7" x="36.6" y="727.6" textLength="244" clip-path="url(#terminal-line-29)">Workspace&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"> </text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r7" x="36.6" y="752" textLength="85.4" clip-path="url(#terminal-line-30)">&#160;&#160;gmail</text><text class="terminal-r8" x="122" y="752" textLength="158.6" clip-path="url(#terminal-line-30)">&#160;&#160;[connector]</text><text class="terminal-r8" x="280.6" y="752" textLength="109.8" clip-path="url(#terminal-line-30)">&#160;&#160;3&#160;tools</text><text class="terminal-r9" x="414.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r8" x="427" y="752" textLength="122" clip-path="url(#terminal-line-30)">&#160;connected</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"> </text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r7" x="36.6" y="752" textLength="244" clip-path="url(#terminal-line-30)">Workspace&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">
</text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="36.6" y="776.4" textLength="85.4" clip-path="url(#terminal-line-31)">&#160;&#160;slack</text><text class="terminal-r10" x="122" y="776.4" textLength="158.6" clip-path="url(#terminal-line-31)">&#160;&#160;[connector]</text><text class="terminal-r10" x="280.6" y="776.4" textLength="109.8" clip-path="url(#terminal-line-31)">&#160;&#160;2&#160;tools</text><text class="terminal-r11" x="414.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r10" x="427" y="776.4" textLength="122" clip-path="url(#terminal-line-31)">&#160;connected</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"> </text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r7" x="36.6" y="776.4" textLength="85.4" clip-path="url(#terminal-line-31)">&#160;&#160;gmail</text><text class="terminal-r8" x="122" y="776.4" textLength="158.6" clip-path="url(#terminal-line-31)">&#160;&#160;[connector]</text><text class="terminal-r8" x="280.6" y="776.4" textLength="109.8" clip-path="url(#terminal-line-31)">&#160;&#160;3&#160;tools</text><text class="terminal-r9" x="414.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r8" x="427" y="776.4" textLength="122" clip-path="url(#terminal-line-31)">&#160;connected</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)">
</text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"> </text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="36.6" y="800.8" textLength="85.4" clip-path="url(#terminal-line-32)">&#160;&#160;slack</text><text class="terminal-r10" x="122" y="800.8" textLength="158.6" clip-path="url(#terminal-line-32)">&#160;&#160;[connector]</text><text class="terminal-r10" x="280.6" y="800.8" textLength="109.8" clip-path="url(#terminal-line-32)">&#160;&#160;2&#160;tools</text><text class="terminal-r11" x="414.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r10" x="427" y="800.8" textLength="122" clip-path="url(#terminal-line-32)">&#160;connected</text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)">
</text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="878.4" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"> </text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="878.4" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)">
</text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)"> </text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)">
</text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text> </text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text>

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Before After
Before After

View file

@ -163,7 +163,7 @@
</g> </g>
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)"> <g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<rect fill="#608ab1" x="36.6" y="709.1" width="85.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="122" y="709.1" width="158.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="280.6" y="709.1" width="122" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="402.6" y="709.1" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="427" y="709.1" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="439.2" y="709.1" width="122" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="561.2" y="709.1" width="866.2" height="24.65" shape-rendering="crispEdges"/> <rect fill="#608ab1" x="36.6" y="733.5" width="85.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="122" y="733.5" width="158.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="280.6" y="733.5" width="122" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="402.6" y="733.5" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="427" y="733.5" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="439.2" y="733.5" width="122" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="561.2" y="733.5" width="866.2" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-matrix"> <g class="terminal-matrix">
<text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)"> <text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)"> </text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)">
@ -181,23 +181,23 @@
</text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)"> </text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)">
</text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)"> </text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)">
</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)"> </text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="0" y="410.4" textLength="134.2" clip-path="url(#terminal-line-16)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="410.4" textLength="146.4" clip-path="url(#terminal-line-16)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="410.4" textLength="122" clip-path="url(#terminal-line-16)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="410.4" textLength="244" clip-path="url(#terminal-line-16)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="410.4" textLength="256.2" clip-path="url(#terminal-line-16)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="0" y="434.8" textLength="134.2" clip-path="url(#terminal-line-17)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="434.8" textLength="597.8" clip-path="url(#terminal-line-17)">1&#160;model&#160;·&#160;3&#160;connectors&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="0" y="434.8" textLength="134.2" clip-path="url(#terminal-line-17)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="434.8" textLength="146.4" clip-path="url(#terminal-line-17)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="434.8" textLength="122" clip-path="url(#terminal-line-17)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="434.8" textLength="244" clip-path="url(#terminal-line-17)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="434.8" textLength="256.2" clip-path="url(#terminal-line-17)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="459.2" textLength="61" clip-path="url(#terminal-line-18)">Type&#160;</text><text class="terminal-r3" x="231.8" y="459.2" textLength="61" clip-path="url(#terminal-line-18)">/help</text><text class="terminal-r1" x="292.8" y="459.2" textLength="256.2" clip-path="url(#terminal-line-18)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="459.2" textLength="597.8" clip-path="url(#terminal-line-18)">1&#160;model&#160;·&#160;3&#160;connectors&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="483.6" textLength="61" clip-path="url(#terminal-line-19)">Type&#160;</text><text class="terminal-r3" x="231.8" y="483.6" textLength="61" clip-path="url(#terminal-line-19)">/help</text><text class="terminal-r1" x="292.8" y="483.6" textLength="256.2" clip-path="url(#terminal-line-19)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r4" x="0" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"></text><text class="terminal-r2" x="24.4" y="532.4" textLength="48.8" clip-path="url(#terminal-line-21)">/mcp</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r5" x="24.4" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"></text><text class="terminal-r1" x="48.8" y="556.8" textLength="256.2" clip-path="url(#terminal-line-22)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r4" x="0" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"></text><text class="terminal-r2" x="24.4" y="556.8" textLength="48.8" clip-path="url(#terminal-line-22)">/mcp</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r5" x="24.4" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r1" x="48.8" y="581.2" textLength="256.2" clip-path="url(#terminal-line-23)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-r5" x="0" y="630" textLength="1464" clip-path="url(#terminal-line-25)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r6" x="24.4" y="654.4" textLength="292.8" clip-path="url(#terminal-line-26)">MCP&#160;Servers&#160;&amp;&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </text><text class="terminal-r5" x="0" y="654.4" textLength="1464" clip-path="url(#terminal-line-26)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r5" x="1451.8" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"> </text><text class="terminal-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r6" x="24.4" y="678.8" textLength="292.8" clip-path="url(#terminal-line-27)">MCP&#160;Servers&#160;&amp;&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r7" x="36.6" y="703.2" textLength="244" clip-path="url(#terminal-line-28)">Workspace&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"> </text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r7" x="36.6" y="727.6" textLength="85.4" clip-path="url(#terminal-line-29)">&#160;&#160;alpha</text><text class="terminal-r8" x="122" y="727.6" textLength="158.6" clip-path="url(#terminal-line-29)">&#160;&#160;[connector]</text><text class="terminal-r8" x="280.6" y="727.6" textLength="122" clip-path="url(#terminal-line-29)">&#160;&#160;1&#160;tool&#160;&#160;</text><text class="terminal-r9" x="427" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r8" x="439.2" y="727.6" textLength="122" clip-path="url(#terminal-line-29)">&#160;connected</text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"> </text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r7" x="36.6" y="727.6" textLength="244" clip-path="url(#terminal-line-29)">Workspace&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="36.6" y="752" textLength="85.4" clip-path="url(#terminal-line-30)">&#160;&#160;beta&#160;</text><text class="terminal-r10" x="122" y="752" textLength="158.6" clip-path="url(#terminal-line-30)">&#160;&#160;[connector]</text><text class="terminal-r10" x="280.6" y="752" textLength="122" clip-path="url(#terminal-line-30)">&#160;&#160;no&#160;tools</text><text class="terminal-r10" x="427" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r10" x="439.2" y="752" textLength="170.8" clip-path="url(#terminal-line-30)">&#160;not&#160;connected</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"> </text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r7" x="36.6" y="752" textLength="85.4" clip-path="url(#terminal-line-30)">&#160;&#160;alpha</text><text class="terminal-r8" x="122" y="752" textLength="158.6" clip-path="url(#terminal-line-30)">&#160;&#160;[connector]</text><text class="terminal-r8" x="280.6" y="752" textLength="122" clip-path="url(#terminal-line-30)">&#160;&#160;1&#160;tool&#160;&#160;</text><text class="terminal-r9" x="427" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r8" x="439.2" y="752" textLength="122" clip-path="url(#terminal-line-30)">&#160;connected</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">
</text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="36.6" y="776.4" textLength="85.4" clip-path="url(#terminal-line-31)">&#160;&#160;zeta&#160;</text><text class="terminal-r10" x="122" y="776.4" textLength="158.6" clip-path="url(#terminal-line-31)">&#160;&#160;[connector]</text><text class="terminal-r10" x="280.6" y="776.4" textLength="122" clip-path="url(#terminal-line-31)">&#160;&#160;no&#160;tools</text><text class="terminal-r10" x="427" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r10" x="439.2" y="776.4" textLength="170.8" clip-path="url(#terminal-line-31)">&#160;not&#160;connected</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"> </text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="36.6" y="776.4" textLength="85.4" clip-path="url(#terminal-line-31)">&#160;&#160;beta&#160;</text><text class="terminal-r10" x="122" y="776.4" textLength="158.6" clip-path="url(#terminal-line-31)">&#160;&#160;[connector]</text><text class="terminal-r10" x="280.6" y="776.4" textLength="122" clip-path="url(#terminal-line-31)">&#160;&#160;no&#160;tools</text><text class="terminal-r10" x="427" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r10" x="439.2" y="776.4" textLength="170.8" clip-path="url(#terminal-line-31)">&#160;not&#160;connected</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)">
</text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"> </text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="36.6" y="800.8" textLength="85.4" clip-path="url(#terminal-line-32)">&#160;&#160;zeta&#160;</text><text class="terminal-r10" x="122" y="800.8" textLength="158.6" clip-path="url(#terminal-line-32)">&#160;&#160;[connector]</text><text class="terminal-r10" x="280.6" y="800.8" textLength="122" clip-path="url(#terminal-line-32)">&#160;&#160;no&#160;tools</text><text class="terminal-r10" x="427" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r10" x="439.2" y="800.8" textLength="170.8" clip-path="url(#terminal-line-32)">&#160;not&#160;connected</text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)">
</text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="878.4" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"> </text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="878.4" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)">
</text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)"> </text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)">
</text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text> </text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text>

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Before After
Before After

View file

@ -160,7 +160,7 @@
</g> </g>
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)"> <g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<rect fill="#608ab1" x="36.6" y="733.5" width="183" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="219.6" y="733.5" width="317.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="536.8" y="733.5" width="890.6" height="24.65" shape-rendering="crispEdges"/> <rect fill="#608ab1" x="36.6" y="757.9" width="183" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="219.6" y="757.9" width="317.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="536.8" y="757.9" width="890.6" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-matrix"> <g class="terminal-matrix">
<text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)"> <text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)"> </text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)">
@ -180,21 +180,21 @@
</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)"> </text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="459.2" textLength="146.4" clip-path="url(#terminal-line-18)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="459.2" textLength="122" clip-path="url(#terminal-line-18)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="459.2" textLength="244" clip-path="url(#terminal-line-18)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="459.2" textLength="256.2" clip-path="url(#terminal-line-18)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="483.6" textLength="585.6" clip-path="url(#terminal-line-19)">1&#160;model&#160;·&#160;2&#160;connectors&#160;·&#160;1&#160;MCP&#160;server&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="483.6" textLength="146.4" clip-path="url(#terminal-line-19)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="483.6" textLength="122" clip-path="url(#terminal-line-19)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="483.6" textLength="244" clip-path="url(#terminal-line-19)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="483.6" textLength="256.2" clip-path="url(#terminal-line-19)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="0" y="508" textLength="134.2" clip-path="url(#terminal-line-20)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="508" textLength="61" clip-path="url(#terminal-line-20)">Type&#160;</text><text class="terminal-r3" x="231.8" y="508" textLength="61" clip-path="url(#terminal-line-20)">/help</text><text class="terminal-r1" x="292.8" y="508" textLength="256.2" clip-path="url(#terminal-line-20)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r1" x="0" y="508" textLength="134.2" clip-path="url(#terminal-line-20)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="508" textLength="585.6" clip-path="url(#terminal-line-20)">1&#160;model&#160;·&#160;2&#160;connectors&#160;·&#160;1&#160;MCP&#160;server&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r1" x="0" y="532.4" textLength="134.2" clip-path="url(#terminal-line-21)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="532.4" textLength="61" clip-path="url(#terminal-line-21)">Type&#160;</text><text class="terminal-r3" x="231.8" y="532.4" textLength="61" clip-path="url(#terminal-line-21)">/help</text><text class="terminal-r1" x="292.8" y="532.4" textLength="256.2" clip-path="url(#terminal-line-21)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r4" x="0" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r2" x="24.4" y="581.2" textLength="48.8" clip-path="url(#terminal-line-23)">/mcp</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r5" x="24.4" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r1" x="48.8" y="605.6" textLength="256.2" clip-path="url(#terminal-line-24)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r4" x="0" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r2" x="24.4" y="605.6" textLength="48.8" clip-path="url(#terminal-line-24)">/mcp</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </text><text class="terminal-r5" x="24.4" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r1" x="48.8" y="630" textLength="256.2" clip-path="url(#terminal-line-25)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r5" x="0" y="678.8" textLength="1464" clip-path="url(#terminal-line-27)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"> </text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r6" x="24.4" y="703.2" textLength="195.2" clip-path="url(#terminal-line-28)">Connector:&#160;slack</text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"> </text><text class="terminal-r5" x="0" y="703.2" textLength="1464" clip-path="url(#terminal-line-28)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"> </text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r6" x="24.4" y="727.6" textLength="195.2" clip-path="url(#terminal-line-29)">Connector:&#160;slack</text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r7" x="36.6" y="752" textLength="183" clip-path="url(#terminal-line-30)">search_messages</text><text class="terminal-r7" x="219.6" y="752" textLength="317.2" clip-path="url(#terminal-line-30)">&#160;&#160;-&#160;&#160;Search&#160;Slack&#160;messages</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"> </text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">
</text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r7" x="36.6" y="776.4" textLength="146.4" clip-path="url(#terminal-line-31)">send_message</text><text class="terminal-r1" x="183" y="776.4" textLength="305" clip-path="url(#terminal-line-31)">&#160;&#160;-&#160;&#160;Send&#160;a&#160;Slack&#160;message</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"> </text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r7" x="36.6" y="776.4" textLength="183" clip-path="url(#terminal-line-31)">search_messages</text><text class="terminal-r7" x="219.6" y="776.4" textLength="317.2" clip-path="url(#terminal-line-31)">&#160;&#160;-&#160;&#160;Search&#160;Slack&#160;messages</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)">
</text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"> </text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r7" x="36.6" y="800.8" textLength="146.4" clip-path="url(#terminal-line-32)">send_message</text><text class="terminal-r1" x="183" y="800.8" textLength="305" clip-path="url(#terminal-line-32)">&#160;&#160;-&#160;&#160;Send&#160;a&#160;Slack&#160;message</text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)">
</text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="854" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;Backspace&#160;Back&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"> </text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="854" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;Backspace&#160;Back&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)">
</text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)"> </text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)">
</text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text> </text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text>

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before After
Before After

View file

@ -160,7 +160,7 @@
</g> </g>
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)"> <g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<rect fill="#608ab1" x="36.6" y="757.9" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="146.4" y="757.9" width="378.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="524.6" y="757.9" width="902.8" height="24.65" shape-rendering="crispEdges"/> <rect fill="#608ab1" x="36.6" y="782.3" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="146.4" y="782.3" width="378.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="524.6" y="782.3" width="902.8" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-matrix"> <g class="terminal-matrix">
<text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)"> <text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)"> </text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)">
@ -181,20 +181,20 @@
</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="483.6" textLength="146.4" clip-path="url(#terminal-line-19)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="483.6" textLength="122" clip-path="url(#terminal-line-19)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="483.6" textLength="244" clip-path="url(#terminal-line-19)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="483.6" textLength="256.2" clip-path="url(#terminal-line-19)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="0" y="508" textLength="134.2" clip-path="url(#terminal-line-20)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="508" textLength="414.8" clip-path="url(#terminal-line-20)">1&#160;model&#160;·&#160;2&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r1" x="0" y="508" textLength="134.2" clip-path="url(#terminal-line-20)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="508" textLength="146.4" clip-path="url(#terminal-line-20)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="508" textLength="122" clip-path="url(#terminal-line-20)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="508" textLength="244" clip-path="url(#terminal-line-20)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="508" textLength="256.2" clip-path="url(#terminal-line-20)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r1" x="0" y="532.4" textLength="134.2" clip-path="url(#terminal-line-21)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="532.4" textLength="61" clip-path="url(#terminal-line-21)">Type&#160;</text><text class="terminal-r3" x="231.8" y="532.4" textLength="61" clip-path="url(#terminal-line-21)">/help</text><text class="terminal-r1" x="292.8" y="532.4" textLength="256.2" clip-path="url(#terminal-line-21)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r1" x="0" y="532.4" textLength="134.2" clip-path="url(#terminal-line-21)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="532.4" textLength="414.8" clip-path="url(#terminal-line-21)">1&#160;model&#160;·&#160;2&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="0" y="556.8" textLength="134.2" clip-path="url(#terminal-line-22)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="556.8" textLength="61" clip-path="url(#terminal-line-22)">Type&#160;</text><text class="terminal-r3" x="231.8" y="556.8" textLength="61" clip-path="url(#terminal-line-22)">/help</text><text class="terminal-r1" x="292.8" y="556.8" textLength="256.2" clip-path="url(#terminal-line-22)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r4" x="0" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r2" x="24.4" y="605.6" textLength="48.8" clip-path="url(#terminal-line-24)">/mcp</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-r5" x="24.4" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r1" x="48.8" y="630" textLength="256.2" clip-path="url(#terminal-line-25)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </text><text class="terminal-r4" x="0" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r2" x="24.4" y="630" textLength="48.8" clip-path="url(#terminal-line-25)">/mcp</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </text><text class="terminal-r5" x="24.4" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r1" x="48.8" y="654.4" textLength="256.2" clip-path="url(#terminal-line-26)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"> </text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r5" x="0" y="703.2" textLength="1464" clip-path="url(#terminal-line-28)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"> </text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r6" x="24.4" y="727.6" textLength="268.4" clip-path="url(#terminal-line-29)">MCP&#160;Server:&#160;filesystem</text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"> </text><text class="terminal-r5" x="0" y="727.6" textLength="1464" clip-path="url(#terminal-line-29)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"> </text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r6" x="24.4" y="752" textLength="268.4" clip-path="url(#terminal-line-30)">MCP&#160;Server:&#160;filesystem</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">
</text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r7" x="36.6" y="776.4" textLength="109.8" clip-path="url(#terminal-line-31)">fake_tool</text><text class="terminal-r7" x="146.4" y="776.4" textLength="378.2" clip-path="url(#terminal-line-31)">&#160;&#160;-&#160;&#160;A&#160;fake&#160;tool&#160;for&#160;filesystem</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"> </text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)">
</text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"> </text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r7" x="36.6" y="800.8" textLength="109.8" clip-path="url(#terminal-line-32)">fake_tool</text><text class="terminal-r7" x="146.4" y="800.8" textLength="378.2" clip-path="url(#terminal-line-32)">&#160;&#160;-&#160;&#160;A&#160;fake&#160;tool&#160;for&#160;filesystem</text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)">
</text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="854" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;Backspace&#160;Back&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"> </text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="854" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;Backspace&#160;Back&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)">
</text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)"> </text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)">
</text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text> </text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text>

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

@ -0,0 +1,206 @@
<svg class="rich-terminal" viewBox="0 0 1482 928.4" xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
font-style: normal;
font-weight: 400;
}
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Bold"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
font-style: bold;
font-weight: 700;
}
.terminal-matrix {
font-family: Fira Code, monospace;
font-size: 20px;
line-height: 24.4px;
font-variant-east-asian: full-width;
}
.terminal-title {
font-size: 18px;
font-weight: bold;
font-family: arial;
}
.terminal-r1 { fill: #c5c8c6 }
.terminal-r2 { fill: #ff8205;font-weight: bold }
.terminal-r3 { fill: #68a0b3 }
.terminal-r4 { fill: #ff8205 }
.terminal-r5 { fill: #9a9b99 }
.terminal-r6 { fill: #608ab1;font-weight: bold }
.terminal-r7 { fill: #c5c8c6;font-weight: bold }
.terminal-r8 { fill: #868887 }
.terminal-r9 { fill: #98a84b }
.terminal-r10 { fill: #9cafbd;font-weight: bold }
</style>
<defs>
<clipPath id="terminal-clip-terminal">
<rect x="0" y="0" width="1463.0" height="877.4" />
</clipPath>
<clipPath id="terminal-line-0">
<rect x="0" y="1.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-1">
<rect x="0" y="25.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-2">
<rect x="0" y="50.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-3">
<rect x="0" y="74.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-4">
<rect x="0" y="99.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-5">
<rect x="0" y="123.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-6">
<rect x="0" y="147.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-7">
<rect x="0" y="172.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-8">
<rect x="0" y="196.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-9">
<rect x="0" y="221.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-10">
<rect x="0" y="245.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-11">
<rect x="0" y="269.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-12">
<rect x="0" y="294.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-13">
<rect x="0" y="318.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-14">
<rect x="0" y="343.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-15">
<rect x="0" y="367.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-16">
<rect x="0" y="391.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-17">
<rect x="0" y="416.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-18">
<rect x="0" y="440.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-19">
<rect x="0" y="465.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-20">
<rect x="0" y="489.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-21">
<rect x="0" y="513.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-22">
<rect x="0" y="538.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-23">
<rect x="0" y="562.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-24">
<rect x="0" y="587.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-25">
<rect x="0" y="611.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-26">
<rect x="0" y="635.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-27">
<rect x="0" y="660.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-28">
<rect x="0" y="684.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-29">
<rect x="0" y="709.1" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-30">
<rect x="0" y="733.5" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-31">
<rect x="0" y="757.9" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-32">
<rect x="0" y="782.3" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-33">
<rect x="0" y="806.7" width="1464" height="24.65"/>
</clipPath>
<clipPath id="terminal-line-34">
<rect x="0" y="831.1" width="1464" height="24.65"/>
</clipPath>
</defs>
<rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="926.4" rx="8"/><text class="terminal-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">SnapshotTestAppConnectorsMixedState</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
<circle cx="44" cy="0" r="7" fill="#28c840"/>
</g>
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<rect fill="#608ab1" x="36.6" y="757.9" width="85.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="122" y="757.9" width="158.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="280.6" y="757.9" width="122" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="402.6" y="757.9" width="24.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="427" y="757.9" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="439.2" y="757.9" width="170.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="610" y="757.9" width="817.4" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-matrix">
<text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)">
</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
</text><text class="terminal-r1" x="1464" y="93.2" textLength="12.2" clip-path="url(#terminal-line-3)">
</text><text class="terminal-r1" x="1464" y="117.6" textLength="12.2" clip-path="url(#terminal-line-4)">
</text><text class="terminal-r1" x="1464" y="142" textLength="12.2" clip-path="url(#terminal-line-5)">
</text><text class="terminal-r1" x="1464" y="166.4" textLength="12.2" clip-path="url(#terminal-line-6)">
</text><text class="terminal-r1" x="1464" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)">
</text><text class="terminal-r1" x="1464" y="215.2" textLength="12.2" clip-path="url(#terminal-line-8)">
</text><text class="terminal-r1" x="1464" y="239.6" textLength="12.2" clip-path="url(#terminal-line-9)">
</text><text class="terminal-r1" x="1464" y="264" textLength="12.2" clip-path="url(#terminal-line-10)">
</text><text class="terminal-r1" x="1464" y="288.4" textLength="12.2" clip-path="url(#terminal-line-11)">
</text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)">
</text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)">
</text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)">
</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="0" y="434.8" textLength="134.2" clip-path="url(#terminal-line-17)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="434.8" textLength="146.4" clip-path="url(#terminal-line-17)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="434.8" textLength="122" clip-path="url(#terminal-line-17)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="434.8" textLength="244" clip-path="url(#terminal-line-17)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="434.8" textLength="256.2" clip-path="url(#terminal-line-17)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="459.2" textLength="597.8" clip-path="url(#terminal-line-18)">1&#160;model&#160;·&#160;3&#160;connectors&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="483.6" textLength="61" clip-path="url(#terminal-line-19)">Type&#160;</text><text class="terminal-r3" x="231.8" y="483.6" textLength="61" clip-path="url(#terminal-line-19)">/help</text><text class="terminal-r1" x="292.8" y="483.6" textLength="256.2" clip-path="url(#terminal-line-19)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r4" x="0" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"></text><text class="terminal-r2" x="24.4" y="556.8" textLength="48.8" clip-path="url(#terminal-line-22)">/mcp</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r5" x="24.4" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r1" x="48.8" y="581.2" textLength="256.2" clip-path="url(#terminal-line-23)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r5" x="0" y="654.4" textLength="1464" clip-path="url(#terminal-line-26)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r6" x="24.4" y="678.8" textLength="292.8" clip-path="url(#terminal-line-27)">MCP&#160;Servers&#160;&amp;&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r7" x="36.6" y="727.6" textLength="244" clip-path="url(#terminal-line-29)">Workspace&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="36.6" y="752" textLength="85.4" clip-path="url(#terminal-line-30)">&#160;&#160;alpha</text><text class="terminal-r8" x="122" y="752" textLength="158.6" clip-path="url(#terminal-line-30)">&#160;&#160;[connector]</text><text class="terminal-r8" x="280.6" y="752" textLength="122" clip-path="url(#terminal-line-30)">&#160;&#160;1&#160;tool&#160;&#160;</text><text class="terminal-r9" x="427" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r8" x="439.2" y="752" textLength="122" clip-path="url(#terminal-line-30)">&#160;connected</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">
</text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r7" x="36.6" y="776.4" textLength="85.4" clip-path="url(#terminal-line-31)">&#160;&#160;beta&#160;</text><text class="terminal-r10" x="122" y="776.4" textLength="158.6" clip-path="url(#terminal-line-31)">&#160;&#160;[connector]</text><text class="terminal-r10" x="280.6" y="776.4" textLength="122" clip-path="url(#terminal-line-31)">&#160;&#160;no&#160;tools</text><text class="terminal-r10" x="427" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r10" x="439.2" y="776.4" textLength="170.8" clip-path="url(#terminal-line-31)">&#160;not&#160;connected</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)">
</text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="36.6" y="800.8" textLength="85.4" clip-path="url(#terminal-line-32)">&#160;&#160;zeta&#160;</text><text class="terminal-r8" x="122" y="800.8" textLength="158.6" clip-path="url(#terminal-line-32)">&#160;&#160;[connector]</text><text class="terminal-r8" x="280.6" y="800.8" textLength="122" clip-path="url(#terminal-line-32)">&#160;&#160;no&#160;tools</text><text class="terminal-r8" x="427" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r8" x="439.2" y="800.8" textLength="170.8" clip-path="url(#terminal-line-32)">&#160;not&#160;connected</text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)">
</text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="902.8" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;Enter&#160;Authenticate&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)">
</text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)">
</text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -162,7 +162,7 @@
</g> </g>
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)"> <g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<rect fill="#608ab1" x="36.6" y="733.5" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="183" y="733.5" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="292.8" y="733.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="390.4" y="733.5" width="1037" height="24.65" shape-rendering="crispEdges"/> <rect fill="#608ab1" x="36.6" y="757.9" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="183" y="757.9" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="292.8" y="757.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="390.4" y="757.9" width="1037" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-matrix"> <g class="terminal-matrix">
<text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)"> <text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)"> </text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)">
@ -181,22 +181,22 @@
</text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)"> </text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)">
</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)"> </text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="0" y="434.8" textLength="134.2" clip-path="url(#terminal-line-17)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="434.8" textLength="146.4" clip-path="url(#terminal-line-17)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="434.8" textLength="122" clip-path="url(#terminal-line-17)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="434.8" textLength="244" clip-path="url(#terminal-line-17)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="434.8" textLength="256.2" clip-path="url(#terminal-line-17)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="459.2" textLength="414.8" clip-path="url(#terminal-line-18)">1&#160;model&#160;·&#160;2&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="459.2" textLength="146.4" clip-path="url(#terminal-line-18)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="459.2" textLength="122" clip-path="url(#terminal-line-18)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="459.2" textLength="244" clip-path="url(#terminal-line-18)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="459.2" textLength="256.2" clip-path="url(#terminal-line-18)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="483.6" textLength="61" clip-path="url(#terminal-line-19)">Type&#160;</text><text class="terminal-r3" x="231.8" y="483.6" textLength="61" clip-path="url(#terminal-line-19)">/help</text><text class="terminal-r1" x="292.8" y="483.6" textLength="256.2" clip-path="url(#terminal-line-19)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="483.6" textLength="414.8" clip-path="url(#terminal-line-19)">1&#160;model&#160;·&#160;2&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r1" x="0" y="508" textLength="134.2" clip-path="url(#terminal-line-20)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="508" textLength="61" clip-path="url(#terminal-line-20)">Type&#160;</text><text class="terminal-r3" x="231.8" y="508" textLength="61" clip-path="url(#terminal-line-20)">/help</text><text class="terminal-r1" x="292.8" y="508" textLength="256.2" clip-path="url(#terminal-line-20)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r4" x="0" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"></text><text class="terminal-r2" x="24.4" y="556.8" textLength="48.8" clip-path="url(#terminal-line-22)">/mcp</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r5" x="24.4" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r1" x="48.8" y="581.2" textLength="256.2" clip-path="url(#terminal-line-23)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r4" x="0" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r2" x="24.4" y="581.2" textLength="48.8" clip-path="url(#terminal-line-23)">/mcp</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r5" x="24.4" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r1" x="48.8" y="605.6" textLength="256.2" clip-path="url(#terminal-line-24)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r5" x="0" y="654.4" textLength="1464" clip-path="url(#terminal-line-26)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r6" x="24.4" y="678.8" textLength="134.2" clip-path="url(#terminal-line-27)">MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"> </text><text class="terminal-r5" x="0" y="678.8" textLength="1464" clip-path="url(#terminal-line-27)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"> </text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r6" x="24.4" y="703.2" textLength="134.2" clip-path="url(#terminal-line-28)">MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r7" x="36.6" y="727.6" textLength="207.4" clip-path="url(#terminal-line-29)">Local&#160;MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"> </text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r7" x="36.6" y="752" textLength="146.4" clip-path="url(#terminal-line-30)">&#160;&#160;filesystem</text><text class="terminal-r8" x="183" y="752" textLength="109.8" clip-path="url(#terminal-line-30)">&#160;&#160;[stdio]</text><text class="terminal-r8" x="292.8" y="752" textLength="97.6" clip-path="url(#terminal-line-30)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"> </text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r7" x="36.6" y="752" textLength="207.4" clip-path="url(#terminal-line-30)">Local&#160;MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">
</text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="36.6" y="776.4" textLength="146.4" clip-path="url(#terminal-line-31)">&#160;&#160;search&#160;&#160;&#160;&#160;</text><text class="terminal-r9" x="183" y="776.4" textLength="109.8" clip-path="url(#terminal-line-31)">&#160;&#160;[http]&#160;</text><text class="terminal-r9" x="292.8" y="776.4" textLength="97.6" clip-path="url(#terminal-line-31)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"> </text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r7" x="36.6" y="776.4" textLength="146.4" clip-path="url(#terminal-line-31)">&#160;&#160;filesystem</text><text class="terminal-r8" x="183" y="776.4" textLength="109.8" clip-path="url(#terminal-line-31)">&#160;&#160;[stdio]</text><text class="terminal-r8" x="292.8" y="776.4" textLength="97.6" clip-path="url(#terminal-line-31)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)">
</text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"> </text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="36.6" y="800.8" textLength="146.4" clip-path="url(#terminal-line-32)">&#160;&#160;search&#160;&#160;&#160;&#160;</text><text class="terminal-r9" x="183" y="800.8" textLength="109.8" clip-path="url(#terminal-line-32)">&#160;&#160;[http]&#160;</text><text class="terminal-r9" x="292.8" y="800.8" textLength="97.6" clip-path="url(#terminal-line-32)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)">
</text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="878.4" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"> </text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="878.4" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)">
</text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)"> </text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)">
</text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text> </text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text>

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before After
Before After

View file

@ -162,7 +162,7 @@
</g> </g>
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)"> <g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<rect fill="#608ab1" x="36.6" y="757.9" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="183" y="757.9" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="292.8" y="757.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="390.4" y="757.9" width="1037" height="24.65" shape-rendering="crispEdges"/> <rect fill="#608ab1" x="36.6" y="782.3" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="183" y="782.3" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="292.8" y="782.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="390.4" y="782.3" width="1037" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-matrix"> <g class="terminal-matrix">
<text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)"> <text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)"> </text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)">
@ -181,22 +181,22 @@
</text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)"> </text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)">
</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)"> </text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="0" y="434.8" textLength="134.2" clip-path="url(#terminal-line-17)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="434.8" textLength="146.4" clip-path="url(#terminal-line-17)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="434.8" textLength="122" clip-path="url(#terminal-line-17)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="434.8" textLength="244" clip-path="url(#terminal-line-17)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="434.8" textLength="256.2" clip-path="url(#terminal-line-17)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="459.2" textLength="414.8" clip-path="url(#terminal-line-18)">1&#160;model&#160;·&#160;2&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="459.2" textLength="146.4" clip-path="url(#terminal-line-18)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="459.2" textLength="122" clip-path="url(#terminal-line-18)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="459.2" textLength="244" clip-path="url(#terminal-line-18)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="459.2" textLength="256.2" clip-path="url(#terminal-line-18)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="483.6" textLength="61" clip-path="url(#terminal-line-19)">Type&#160;</text><text class="terminal-r3" x="231.8" y="483.6" textLength="61" clip-path="url(#terminal-line-19)">/help</text><text class="terminal-r1" x="292.8" y="483.6" textLength="256.2" clip-path="url(#terminal-line-19)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="483.6" textLength="414.8" clip-path="url(#terminal-line-19)">1&#160;model&#160;·&#160;2&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r1" x="0" y="508" textLength="134.2" clip-path="url(#terminal-line-20)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="508" textLength="61" clip-path="url(#terminal-line-20)">Type&#160;</text><text class="terminal-r3" x="231.8" y="508" textLength="61" clip-path="url(#terminal-line-20)">/help</text><text class="terminal-r1" x="292.8" y="508" textLength="256.2" clip-path="url(#terminal-line-20)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r4" x="0" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"></text><text class="terminal-r2" x="24.4" y="556.8" textLength="48.8" clip-path="url(#terminal-line-22)">/mcp</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r5" x="24.4" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r1" x="48.8" y="581.2" textLength="256.2" clip-path="url(#terminal-line-23)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r4" x="0" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r2" x="24.4" y="581.2" textLength="48.8" clip-path="url(#terminal-line-23)">/mcp</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r5" x="24.4" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r1" x="48.8" y="605.6" textLength="256.2" clip-path="url(#terminal-line-24)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r5" x="0" y="654.4" textLength="1464" clip-path="url(#terminal-line-26)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r6" x="24.4" y="678.8" textLength="134.2" clip-path="url(#terminal-line-27)">MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"> </text><text class="terminal-r5" x="0" y="678.8" textLength="1464" clip-path="url(#terminal-line-27)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"> </text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r6" x="24.4" y="703.2" textLength="134.2" clip-path="url(#terminal-line-28)">MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r7" x="36.6" y="727.6" textLength="207.4" clip-path="url(#terminal-line-29)">Local&#160;MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"> </text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="36.6" y="752" textLength="146.4" clip-path="url(#terminal-line-30)">&#160;&#160;filesystem</text><text class="terminal-r8" x="183" y="752" textLength="109.8" clip-path="url(#terminal-line-30)">&#160;&#160;[stdio]</text><text class="terminal-r8" x="292.8" y="752" textLength="97.6" clip-path="url(#terminal-line-30)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"> </text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r7" x="36.6" y="752" textLength="207.4" clip-path="url(#terminal-line-30)">Local&#160;MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">
</text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r7" x="36.6" y="776.4" textLength="146.4" clip-path="url(#terminal-line-31)">&#160;&#160;search&#160;&#160;&#160;&#160;</text><text class="terminal-r9" x="183" y="776.4" textLength="109.8" clip-path="url(#terminal-line-31)">&#160;&#160;[http]&#160;</text><text class="terminal-r9" x="292.8" y="776.4" textLength="97.6" clip-path="url(#terminal-line-31)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"> </text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="36.6" y="776.4" textLength="146.4" clip-path="url(#terminal-line-31)">&#160;&#160;filesystem</text><text class="terminal-r8" x="183" y="776.4" textLength="109.8" clip-path="url(#terminal-line-31)">&#160;&#160;[stdio]</text><text class="terminal-r8" x="292.8" y="776.4" textLength="97.6" clip-path="url(#terminal-line-31)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)">
</text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"> </text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r7" x="36.6" y="800.8" textLength="146.4" clip-path="url(#terminal-line-32)">&#160;&#160;search&#160;&#160;&#160;&#160;</text><text class="terminal-r9" x="183" y="800.8" textLength="109.8" clip-path="url(#terminal-line-32)">&#160;&#160;[http]&#160;</text><text class="terminal-r9" x="292.8" y="800.8" textLength="97.6" clip-path="url(#terminal-line-32)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)">
</text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="878.4" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"> </text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="878.4" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)">
</text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)"> </text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)">
</text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text> </text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text>

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before After
Before After

View file

@ -162,7 +162,7 @@
</g> </g>
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)"> <g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<rect fill="#608ab1" x="36.6" y="733.5" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="183" y="733.5" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="292.8" y="733.5" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="390.4" y="733.5" width="1037" height="24.65" shape-rendering="crispEdges"/> <rect fill="#608ab1" x="36.6" y="757.9" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="183" y="757.9" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="292.8" y="757.9" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="390.4" y="757.9" width="1037" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-matrix"> <g class="terminal-matrix">
<text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)"> <text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)"> </text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)">
@ -181,22 +181,22 @@
</text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)"> </text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)">
</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)"> </text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="0" y="434.8" textLength="134.2" clip-path="url(#terminal-line-17)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="434.8" textLength="146.4" clip-path="url(#terminal-line-17)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="434.8" textLength="122" clip-path="url(#terminal-line-17)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="434.8" textLength="244" clip-path="url(#terminal-line-17)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="434.8" textLength="256.2" clip-path="url(#terminal-line-17)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="459.2" textLength="414.8" clip-path="url(#terminal-line-18)">1&#160;model&#160;·&#160;2&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="459.2" textLength="146.4" clip-path="url(#terminal-line-18)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="459.2" textLength="122" clip-path="url(#terminal-line-18)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="459.2" textLength="244" clip-path="url(#terminal-line-18)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="459.2" textLength="256.2" clip-path="url(#terminal-line-18)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="483.6" textLength="61" clip-path="url(#terminal-line-19)">Type&#160;</text><text class="terminal-r3" x="231.8" y="483.6" textLength="61" clip-path="url(#terminal-line-19)">/help</text><text class="terminal-r1" x="292.8" y="483.6" textLength="256.2" clip-path="url(#terminal-line-19)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="483.6" textLength="414.8" clip-path="url(#terminal-line-19)">1&#160;model&#160;·&#160;2&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r1" x="0" y="508" textLength="134.2" clip-path="url(#terminal-line-20)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="508" textLength="61" clip-path="url(#terminal-line-20)">Type&#160;</text><text class="terminal-r3" x="231.8" y="508" textLength="61" clip-path="url(#terminal-line-20)">/help</text><text class="terminal-r1" x="292.8" y="508" textLength="256.2" clip-path="url(#terminal-line-20)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r4" x="0" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"></text><text class="terminal-r2" x="24.4" y="556.8" textLength="48.8" clip-path="url(#terminal-line-22)">/mcp</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r5" x="24.4" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r1" x="48.8" y="581.2" textLength="256.2" clip-path="url(#terminal-line-23)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r4" x="0" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r2" x="24.4" y="581.2" textLength="48.8" clip-path="url(#terminal-line-23)">/mcp</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r5" x="24.4" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r1" x="48.8" y="605.6" textLength="256.2" clip-path="url(#terminal-line-24)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r5" x="0" y="654.4" textLength="1464" clip-path="url(#terminal-line-26)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r6" x="24.4" y="678.8" textLength="134.2" clip-path="url(#terminal-line-27)">MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"> </text><text class="terminal-r5" x="0" y="678.8" textLength="1464" clip-path="url(#terminal-line-27)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"> </text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r6" x="24.4" y="703.2" textLength="134.2" clip-path="url(#terminal-line-28)">MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r7" x="36.6" y="727.6" textLength="207.4" clip-path="url(#terminal-line-29)">Local&#160;MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"> </text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r7" x="36.6" y="752" textLength="146.4" clip-path="url(#terminal-line-30)">&#160;&#160;filesystem</text><text class="terminal-r8" x="183" y="752" textLength="109.8" clip-path="url(#terminal-line-30)">&#160;&#160;[stdio]</text><text class="terminal-r8" x="292.8" y="752" textLength="97.6" clip-path="url(#terminal-line-30)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"> </text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r7" x="36.6" y="752" textLength="207.4" clip-path="url(#terminal-line-30)">Local&#160;MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">
</text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="36.6" y="776.4" textLength="146.4" clip-path="url(#terminal-line-31)">&#160;&#160;search&#160;&#160;&#160;&#160;</text><text class="terminal-r9" x="183" y="776.4" textLength="109.8" clip-path="url(#terminal-line-31)">&#160;&#160;[http]&#160;</text><text class="terminal-r9" x="292.8" y="776.4" textLength="97.6" clip-path="url(#terminal-line-31)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"> </text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r7" x="36.6" y="776.4" textLength="146.4" clip-path="url(#terminal-line-31)">&#160;&#160;filesystem</text><text class="terminal-r8" x="183" y="776.4" textLength="109.8" clip-path="url(#terminal-line-31)">&#160;&#160;[stdio]</text><text class="terminal-r8" x="292.8" y="776.4" textLength="97.6" clip-path="url(#terminal-line-31)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)">
</text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"> </text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="36.6" y="800.8" textLength="146.4" clip-path="url(#terminal-line-32)">&#160;&#160;search&#160;&#160;&#160;&#160;</text><text class="terminal-r9" x="183" y="800.8" textLength="109.8" clip-path="url(#terminal-line-32)">&#160;&#160;[http]&#160;</text><text class="terminal-r9" x="292.8" y="800.8" textLength="97.6" clip-path="url(#terminal-line-32)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)">
</text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="1024.8" clip-path="url(#terminal-line-33)">Refreshed.&#160;&#160;↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"> </text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="1024.8" clip-path="url(#terminal-line-33)">Refreshed.&#160;&#160;↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)">
</text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)"> </text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)">
</text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text> </text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text>

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before After
Before After

View file

@ -160,7 +160,7 @@
</g> </g>
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)"> <g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<rect fill="#608ab1" x="36.6" y="757.9" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="146.4" y="757.9" width="378.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="524.6" y="757.9" width="902.8" height="24.65" shape-rendering="crispEdges"/> <rect fill="#608ab1" x="36.6" y="782.3" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="146.4" y="782.3" width="378.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="524.6" y="782.3" width="902.8" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-matrix"> <g class="terminal-matrix">
<text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)"> <text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)"> </text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)">
@ -181,20 +181,20 @@
</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="483.6" textLength="146.4" clip-path="url(#terminal-line-19)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="483.6" textLength="122" clip-path="url(#terminal-line-19)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="483.6" textLength="244" clip-path="url(#terminal-line-19)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="483.6" textLength="256.2" clip-path="url(#terminal-line-19)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="0" y="508" textLength="134.2" clip-path="url(#terminal-line-20)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="508" textLength="414.8" clip-path="url(#terminal-line-20)">1&#160;model&#160;·&#160;2&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r1" x="0" y="508" textLength="134.2" clip-path="url(#terminal-line-20)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="508" textLength="146.4" clip-path="url(#terminal-line-20)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="508" textLength="122" clip-path="url(#terminal-line-20)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="508" textLength="244" clip-path="url(#terminal-line-20)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="508" textLength="256.2" clip-path="url(#terminal-line-20)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r1" x="0" y="532.4" textLength="134.2" clip-path="url(#terminal-line-21)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="532.4" textLength="61" clip-path="url(#terminal-line-21)">Type&#160;</text><text class="terminal-r3" x="231.8" y="532.4" textLength="61" clip-path="url(#terminal-line-21)">/help</text><text class="terminal-r1" x="292.8" y="532.4" textLength="256.2" clip-path="url(#terminal-line-21)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r1" x="0" y="532.4" textLength="134.2" clip-path="url(#terminal-line-21)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="532.4" textLength="414.8" clip-path="url(#terminal-line-21)">1&#160;model&#160;·&#160;2&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="0" y="556.8" textLength="134.2" clip-path="url(#terminal-line-22)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="556.8" textLength="61" clip-path="url(#terminal-line-22)">Type&#160;</text><text class="terminal-r3" x="231.8" y="556.8" textLength="61" clip-path="url(#terminal-line-22)">/help</text><text class="terminal-r1" x="292.8" y="556.8" textLength="256.2" clip-path="url(#terminal-line-22)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r4" x="0" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r2" x="24.4" y="605.6" textLength="183" clip-path="url(#terminal-line-24)">/mcp&#160;filesystem</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-r5" x="24.4" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r1" x="48.8" y="630" textLength="256.2" clip-path="url(#terminal-line-25)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </text><text class="terminal-r4" x="0" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r2" x="24.4" y="630" textLength="183" clip-path="url(#terminal-line-25)">/mcp&#160;filesystem</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </text><text class="terminal-r5" x="24.4" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r1" x="48.8" y="654.4" textLength="256.2" clip-path="url(#terminal-line-26)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"> </text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r5" x="0" y="703.2" textLength="1464" clip-path="url(#terminal-line-28)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"> </text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r6" x="24.4" y="727.6" textLength="268.4" clip-path="url(#terminal-line-29)">MCP&#160;Server:&#160;filesystem</text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"> </text><text class="terminal-r5" x="0" y="727.6" textLength="1464" clip-path="url(#terminal-line-29)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"> </text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r6" x="24.4" y="752" textLength="268.4" clip-path="url(#terminal-line-30)">MCP&#160;Server:&#160;filesystem</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">
</text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r7" x="36.6" y="776.4" textLength="109.8" clip-path="url(#terminal-line-31)">fake_tool</text><text class="terminal-r7" x="146.4" y="776.4" textLength="378.2" clip-path="url(#terminal-line-31)">&#160;&#160;-&#160;&#160;A&#160;fake&#160;tool&#160;for&#160;filesystem</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"> </text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)">
</text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"> </text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r7" x="36.6" y="800.8" textLength="109.8" clip-path="url(#terminal-line-32)">fake_tool</text><text class="terminal-r7" x="146.4" y="800.8" textLength="378.2" clip-path="url(#terminal-line-32)">&#160;&#160;-&#160;&#160;A&#160;fake&#160;tool&#160;for&#160;filesystem</text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)">
</text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="854" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;Backspace&#160;Back&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"> </text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="854" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;Backspace&#160;Back&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)">
</text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)"> </text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)">
</text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text> </text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text>

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

@ -163,7 +163,7 @@
</g> </g>
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)"> <g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<rect fill="#608ab1" x="36.6" y="660.3" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="183" y="660.3" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="292.8" y="660.3" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="390.4" y="660.3" width="1037" height="24.65" shape-rendering="crispEdges"/> <rect fill="#608ab1" x="36.6" y="684.7" width="146.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="183" y="684.7" width="109.8" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="292.8" y="684.7" width="97.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#608ab1" x="390.4" y="684.7" width="1037" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-matrix"> <g class="terminal-matrix">
<text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)"> <text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)"> </text><text class="terminal-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-line-1)">
@ -179,25 +179,25 @@
</text><text class="terminal-r1" x="1464" y="288.4" textLength="12.2" clip-path="url(#terminal-line-11)"> </text><text class="terminal-r1" x="1464" y="288.4" textLength="12.2" clip-path="url(#terminal-line-11)">
</text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)"> </text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)">
</text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)"> </text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)">
</text><text class="terminal-r1" x="0" y="361.6" textLength="134.2" clip-path="url(#terminal-line-14)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="361.6" textLength="146.4" clip-path="url(#terminal-line-14)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="361.6" textLength="122" clip-path="url(#terminal-line-14)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="361.6" textLength="244" clip-path="url(#terminal-line-14)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="361.6" textLength="256.2" clip-path="url(#terminal-line-14)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)"> </text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)">
</text><text class="terminal-r1" x="0" y="386" textLength="134.2" clip-path="url(#terminal-line-15)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="386" textLength="585.6" clip-path="url(#terminal-line-15)">1&#160;model&#160;·&#160;2&#160;connectors&#160;·&#160;1&#160;MCP&#160;server&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)"> </text><text class="terminal-r1" x="0" y="386" textLength="134.2" clip-path="url(#terminal-line-15)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="386" textLength="146.4" clip-path="url(#terminal-line-15)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="386" textLength="122" clip-path="url(#terminal-line-15)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="386" textLength="244" clip-path="url(#terminal-line-15)">devstral-latest[off]</text><text class="terminal-r1" x="683.2" y="386" textLength="256.2" clip-path="url(#terminal-line-15)">&#160;·&#160;[Subscription]&#160;Pro</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="0" y="410.4" textLength="134.2" clip-path="url(#terminal-line-16)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="410.4" textLength="61" clip-path="url(#terminal-line-16)">Type&#160;</text><text class="terminal-r3" x="231.8" y="410.4" textLength="61" clip-path="url(#terminal-line-16)">/help</text><text class="terminal-r1" x="292.8" y="410.4" textLength="256.2" clip-path="url(#terminal-line-16)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="0" y="410.4" textLength="134.2" clip-path="url(#terminal-line-16)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="410.4" textLength="585.6" clip-path="url(#terminal-line-16)">1&#160;model&#160;·&#160;2&#160;connectors&#160;·&#160;1&#160;MCP&#160;server&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="0" y="434.8" textLength="134.2" clip-path="url(#terminal-line-17)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="434.8" textLength="61" clip-path="url(#terminal-line-17)">Type&#160;</text><text class="terminal-r3" x="231.8" y="434.8" textLength="61" clip-path="url(#terminal-line-17)">/help</text><text class="terminal-r1" x="292.8" y="434.8" textLength="256.2" clip-path="url(#terminal-line-17)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r4" x="0" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"></text><text class="terminal-r2" x="24.4" y="483.6" textLength="48.8" clip-path="url(#terminal-line-19)">/mcp</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r5" x="24.4" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"></text><text class="terminal-r1" x="48.8" y="508" textLength="256.2" clip-path="url(#terminal-line-20)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r4" x="0" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"></text><text class="terminal-r2" x="24.4" y="508" textLength="48.8" clip-path="url(#terminal-line-20)">/mcp</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r5" x="24.4" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"></text><text class="terminal-r1" x="48.8" y="532.4" textLength="256.2" clip-path="url(#terminal-line-21)">MCP&#160;servers&#160;opened...</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r5" x="0" y="581.2" textLength="1464" clip-path="url(#terminal-line-23)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r5" x="0" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r6" x="24.4" y="605.6" textLength="292.8" clip-path="url(#terminal-line-24)">MCP&#160;Servers&#160;&amp;&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r5" x="0" y="605.6" textLength="1464" clip-path="url(#terminal-line-24)">┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-r5" x="0" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r5" x="1451.8" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </text><text class="terminal-r5" x="0" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r6" x="24.4" y="630" textLength="292.8" clip-path="url(#terminal-line-25)">MCP&#160;Servers&#160;&amp;&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r7" x="36.6" y="654.4" textLength="207.4" clip-path="url(#terminal-line-26)">Local&#160;MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </text><text class="terminal-r5" x="0" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r5" x="1451.8" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r7" x="36.6" y="678.8" textLength="146.4" clip-path="url(#terminal-line-27)">&#160;&#160;filesystem</text><text class="terminal-r8" x="183" y="678.8" textLength="109.8" clip-path="url(#terminal-line-27)">&#160;&#160;[stdio]</text><text class="terminal-r8" x="292.8" y="678.8" textLength="97.6" clip-path="url(#terminal-line-27)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"> </text><text class="terminal-r5" x="0" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r7" x="36.6" y="678.8" textLength="207.4" clip-path="url(#terminal-line-27)">Local&#160;MCP&#160;Servers</text><text class="terminal-r5" x="1451.8" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"> </text><text class="terminal-r5" x="0" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r7" x="36.6" y="703.2" textLength="146.4" clip-path="url(#terminal-line-28)">&#160;&#160;filesystem</text><text class="terminal-r8" x="183" y="703.2" textLength="109.8" clip-path="url(#terminal-line-28)">&#160;&#160;[stdio]</text><text class="terminal-r8" x="292.8" y="703.2" textLength="97.6" clip-path="url(#terminal-line-28)">&#160;&#160;1&#160;tool</text><text class="terminal-r5" x="1451.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r7" x="36.6" y="727.6" textLength="244" clip-path="url(#terminal-line-29)">Workspace&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"> </text><text class="terminal-r5" x="0" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r5" x="1451.8" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)"></text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="36.6" y="752" textLength="85.4" clip-path="url(#terminal-line-30)">&#160;&#160;gmail</text><text class="terminal-r9" x="122" y="752" textLength="158.6" clip-path="url(#terminal-line-30)">&#160;&#160;[connector]</text><text class="terminal-r9" x="280.6" y="752" textLength="109.8" clip-path="url(#terminal-line-30)">&#160;&#160;3&#160;tools</text><text class="terminal-r10" x="414.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r9" x="427" y="752" textLength="122" clip-path="url(#terminal-line-30)">&#160;connected</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"> </text><text class="terminal-r5" x="0" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r7" x="36.6" y="752" textLength="244" clip-path="url(#terminal-line-30)">Workspace&#160;Connectors</text><text class="terminal-r5" x="1451.8" y="752" textLength="12.2" clip-path="url(#terminal-line-30)"></text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">
</text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="36.6" y="776.4" textLength="85.4" clip-path="url(#terminal-line-31)">&#160;&#160;slack</text><text class="terminal-r9" x="122" y="776.4" textLength="158.6" clip-path="url(#terminal-line-31)">&#160;&#160;[connector]</text><text class="terminal-r9" x="280.6" y="776.4" textLength="109.8" clip-path="url(#terminal-line-31)">&#160;&#160;2&#160;tools</text><text class="terminal-r10" x="414.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r9" x="427" y="776.4" textLength="122" clip-path="url(#terminal-line-31)">&#160;connected</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"> </text><text class="terminal-r5" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="36.6" y="776.4" textLength="85.4" clip-path="url(#terminal-line-31)">&#160;&#160;gmail</text><text class="terminal-r9" x="122" y="776.4" textLength="158.6" clip-path="url(#terminal-line-31)">&#160;&#160;[connector]</text><text class="terminal-r9" x="280.6" y="776.4" textLength="109.8" clip-path="url(#terminal-line-31)">&#160;&#160;3&#160;tools</text><text class="terminal-r10" x="414.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r9" x="427" y="776.4" textLength="122" clip-path="url(#terminal-line-31)">&#160;connected</text><text class="terminal-r5" x="1451.8" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r1" x="1464" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)">
</text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"> </text><text class="terminal-r5" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="36.6" y="800.8" textLength="85.4" clip-path="url(#terminal-line-32)">&#160;&#160;slack</text><text class="terminal-r9" x="122" y="800.8" textLength="158.6" clip-path="url(#terminal-line-32)">&#160;&#160;[connector]</text><text class="terminal-r9" x="280.6" y="800.8" textLength="109.8" clip-path="url(#terminal-line-32)">&#160;&#160;2&#160;tools</text><text class="terminal-r10" x="414.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r9" x="427" y="800.8" textLength="122" clip-path="url(#terminal-line-32)">&#160;connected</text><text class="terminal-r5" x="1451.8" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r1" x="1464" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)">
</text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="878.4" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"> </text><text class="terminal-r5" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r5" x="24.4" y="825.2" textLength="878.4" clip-path="url(#terminal-line-33)">↑↓&#160;Navigate&#160;&#160;Enter&#160;Show&#160;tools&#160;&#160;D&#160;Disable&#160;&#160;E&#160;Enable&#160;&#160;R&#160;Refresh&#160;&#160;Esc&#160;Close</text><text class="terminal-r5" x="1451.8" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r1" x="1464" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)">
</text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)"> </text><text class="terminal-r5" x="0" y="849.6" textLength="1464" clip-path="url(#terminal-line-34)">└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘</text><text class="terminal-r1" x="1464" y="849.6" textLength="12.2" clip-path="url(#terminal-line-34)">
</text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text> </text><text class="terminal-r5" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r5" x="1256.6" y="874" textLength="207.4" clip-path="url(#terminal-line-35)">0%&#160;of&#160;200k&#160;tokens</text>

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Before After
Before After

View file

@ -253,6 +253,93 @@ def test_snapshot_mcp_with_connectors_overview(snap_compare: SnapCompare) -> Non
) )
# ---------------------------------------------------------------------------
# Connector auth app snapshot tests
# ---------------------------------------------------------------------------
@patch.dict("os.environ", {CONNECTORS_ENV_VAR: "1"})
def test_snapshot_connector_auth_opens_on_disconnected(
snap_compare: SnapCompare,
) -> None:
"""Clicking a disconnected connector opens the auth app."""
async def run_before(pilot: Pilot) -> None:
await _run_mcp_command(pilot, "/mcp")
# In mixed state: alpha (connected) is first, then beta, zeta (disconnected).
# Navigate to a disconnected connector and press enter.
await pilot.press("down") # beta
await pilot.pause(0.1)
await pilot.press("enter") # opens auth app
await pilot.pause(0.5) # wait for auth URL fetch worker
assert snap_compare(
"test_ui_snapshot_mcp_command.py:SnapshotTestAppConnectorsMixedState",
terminal_size=(120, 36),
run_before=run_before,
)
@patch.dict("os.environ", {CONNECTORS_ENV_VAR: "1"})
def test_snapshot_connector_auth_show_url(snap_compare: SnapCompare) -> None:
"""Selecting 'Manually show the URL' reveals the auth URL."""
async def run_before(pilot: Pilot) -> None:
await _run_mcp_command(pilot, "/mcp")
await pilot.press("down") # beta (disconnected)
await pilot.pause(0.1)
await pilot.press("enter") # opens auth app
await pilot.pause(0.5) # wait for auth URL fetch
# Navigate to "Manually show the URL" (3rd selectable option)
await pilot.press("down", "down")
await pilot.pause(0.1)
await pilot.press("enter") # toggle URL display
await pilot.pause(0.1)
assert snap_compare(
"test_ui_snapshot_mcp_command.py:SnapshotTestAppConnectorsMixedState",
terminal_size=(120, 36),
run_before=run_before,
)
@patch.dict("os.environ", {CONNECTORS_ENV_VAR: "1"})
def test_snapshot_connector_auth_back_to_mcp(snap_compare: SnapCompare) -> None:
"""Pressing backspace in the auth app returns to the /mcp menu."""
async def run_before(pilot: Pilot) -> None:
await _run_mcp_command(pilot, "/mcp")
await pilot.press("down") # beta (disconnected)
await pilot.pause(0.1)
await pilot.press("enter") # opens auth app
await pilot.pause(0.5) # wait for auth URL fetch
await pilot.press("backspace") # back to /mcp
await pilot.pause(0.3)
assert snap_compare(
"test_ui_snapshot_mcp_command.py:SnapshotTestAppConnectorsMixedState",
terminal_size=(120, 36),
run_before=run_before,
)
@patch.dict("os.environ", {CONNECTORS_ENV_VAR: "1"})
def test_snapshot_mcp_help_bar_shows_authenticate(snap_compare: SnapCompare) -> None:
"""Help bar shows 'Enter Authenticate' when a disconnected connector is highlighted."""
async def run_before(pilot: Pilot) -> None:
await _run_mcp_command(pilot, "/mcp")
# Navigate to a disconnected connector (beta or zeta)
await pilot.press("down") # beta (disconnected)
await pilot.pause(0.1)
assert snap_compare(
"test_ui_snapshot_mcp_command.py:SnapshotTestAppConnectorsMixedState",
terminal_size=(120, 36),
run_before=run_before,
)
@patch.dict("os.environ", {CONNECTORS_ENV_VAR: "1"}) @patch.dict("os.environ", {CONNECTORS_ENV_VAR: "1"})
def test_snapshot_mcp_connectors_only(snap_compare: SnapCompare) -> None: def test_snapshot_mcp_connectors_only(snap_compare: SnapCompare) -> None:

View file

@ -21,9 +21,11 @@ class FakeConnectorRegistry(ConnectorRegistry):
self._cache = {} self._cache = {}
self._connector_names = [] self._connector_names = []
self._connector_connected = {} self._connector_connected = {}
self._alias_to_id = {}
for connector_name, tools in self._fake_connectors.items(): for connector_name, tools in self._fake_connectors.items():
alias = _normalize_name(connector_name) alias = _normalize_name(connector_name)
connector_id = f"fake-id-{connector_name}" connector_id = f"fake-id-{connector_name}"
self._alias_to_id[alias] = connector_id
tool_map: dict[str, type[BaseTool]] = {} tool_map: dict[str, type[BaseTool]] = {}
for remote in tools: for remote in tools:
proxy_cls = create_connector_proxy_tool_class( proxy_cls = create_connector_proxy_tool_class(
@ -50,3 +52,13 @@ class FakeConnectorRegistry(ConnectorRegistry):
async def get_tools_async(self) -> dict[str, type[BaseTool]]: async def get_tools_async(self) -> dict[str, type[BaseTool]]:
return self.get_tools() return self.get_tools()
async def get_auth_url(self, alias: str) -> str | None:
"""Return a fake auth URL for connectors that have no tools (not connected)."""
if not self.is_connected(alias):
return f"https://fake-auth.example.com/{alias}"
return None
async def refresh_connector_async(self, alias: str) -> dict[str, type[BaseTool]]:
"""No-op refresh for tests."""
return {}

View file

@ -400,3 +400,28 @@ async def test_generic_provider_has_no_metadata_header() -> None:
headers = backend.requests_extra_headers[0] headers = backend.requests_extra_headers[0]
assert headers is not None assert headers is not None
assert "metadata" not in headers assert "metadata" not in headers
@pytest.mark.asyncio
async def test_provider_extra_headers_are_forwarded() -> None:
backend = FakeBackend([mock_llm_chunk(content="Response")])
providers = [
ProviderConfig(
name="custom",
api_base="https://custom.example.com/v1",
extra_headers={"X-Custom-Auth": "token123", "X-Org-Id": "org-456"},
)
]
models = [ModelConfig(name="test-model", provider="custom", alias="test")]
config = build_test_vibe_config(
active_model="test", models=models, providers=providers
)
agent = build_test_agent_loop(config=config, backend=backend)
[_ async for _ in agent.act("Hello")]
assert len(backend.requests_extra_headers) == 1
headers = backend.requests_extra_headers[0]
assert headers is not None
assert headers["X-Custom-Auth"] == "token123"
assert headers["X-Org-Id"] == "org-456"

4
uv.lock generated
View file

@ -3,7 +3,7 @@ revision = 3
requires-python = ">=3.12" requires-python = ">=3.12"
[options] [options]
exclude-newer = "2026-04-21T14:17:22.54525Z" exclude-newer = "2026-04-22T13:12:26.10035Z"
exclude-newer-span = "P7D" exclude-newer-span = "P7D"
[options.exclude-newer-package] [options.exclude-newer-package]
@ -808,7 +808,7 @@ wheels = [
[[package]] [[package]]
name = "mistral-vibe" name = "mistral-vibe"
version = "2.9.0" version = "2.9.1"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "agent-client-protocol" }, { name = "agent-client-protocol" },

View file

@ -3,4 +3,4 @@ from __future__ import annotations
from pathlib import Path from pathlib import Path
VIBE_ROOT = Path(__file__).parent VIBE_ROOT = Path(__file__).parent
__version__ = "2.9.0" __version__ = "2.9.1"

View file

@ -367,7 +367,7 @@ class VibeAcpAgentLoop(AcpAgent):
) )
def _get_acp_tool_overrides(self) -> list[Path]: def _get_acp_tool_overrides(self) -> list[Path]:
overrides = ["todo"] overrides = ["todo", "grep", "web_fetch", "web_search", "skill", "task"]
if self.client_capabilities: if self.client_capabilities:
if self.client_capabilities.terminal: if self.client_capabilities.terminal:
@ -399,6 +399,9 @@ class VibeAcpAgentLoop(AcpAgent):
session.agent_loop.approve_always(tool_name, required_permissions) session.agent_loop.approve_always(tool_name, required_permissions)
return (ApprovalResponse.YES, None) return (ApprovalResponse.YES, None)
case ToolOption.REJECT_ONCE: case ToolOption.REJECT_ONCE:
session.agent_loop.telemetry_client.send_user_cancelled_action(
"reject_approval"
)
return ( return (
ApprovalResponse.NO, ApprovalResponse.NO,
"User rejected the tool call, provide an alternative plan", "User rejected the tool call, provide an alternative plan",
@ -946,6 +949,9 @@ class VibeAcpAgentLoop(AcpAgent):
@override @override
async def cancel(self, session_id: str, **kwargs: Any) -> None: async def cancel(self, session_id: str, **kwargs: Any) -> None:
session = self._get_session(session_id) session = self._get_session(session_id)
session.agent_loop.telemetry_client.send_user_cancelled_action(
"interrupt_agent"
)
await session.cancel_prompt() await session.cancel_prompt()
@override @override

View file

@ -5,7 +5,9 @@ from collections.abc import AsyncGenerator
from pathlib import Path from pathlib import Path
from acp.schema import ( from acp.schema import (
ContentToolCallContent,
TerminalToolCallContent, TerminalToolCallContent,
TextContentBlock,
ToolCallProgress, ToolCallProgress,
ToolCallStart, ToolCallStart,
WaitForTerminalExitResponse, WaitForTerminalExitResponse,
@ -13,6 +15,7 @@ from acp.schema import (
from vibe import VIBE_ROOT from vibe import VIBE_ROOT
from vibe.acp.tools.base import AcpToolState, BaseAcpTool from vibe.acp.tools.base import AcpToolState, BaseAcpTool
from vibe.acp.tools.session_update import resolve_kind
from vibe.core.logger import logger from vibe.core.logger import logger
from vibe.core.tools.base import BaseToolState, InvokeContext, ToolError from vibe.core.tools.base import BaseToolState, InvokeContext, ToolError
from vibe.core.tools.builtins.bash import Bash as CoreBashTool, BashArgs, BashResult from vibe.core.tools.builtins.bash import Bash as CoreBashTool, BashArgs, BashResult
@ -116,9 +119,10 @@ class Bash(CoreBashTool, BaseAcpTool[AcpBashState]):
session_update="tool_call", session_update="tool_call",
title="bash", title="bash",
tool_call_id=event.tool_call_id, tool_call_id=event.tool_call_id,
kind="execute", kind=resolve_kind(event.tool_name),
content=None, content=None,
raw_input=None, raw_input=None,
field_meta={"tool_name": event.tool_name},
) )
if not isinstance(event.args, BashArgs): if not isinstance(event.args, BashArgs):
raise ValueError(f"Unexpected tool args: {event.args}") raise ValueError(f"Unexpected tool args: {event.args}")
@ -128,8 +132,9 @@ class Bash(CoreBashTool, BaseAcpTool[AcpBashState]):
title=Bash.get_summary(event.args), title=Bash.get_summary(event.args),
content=None, content=None,
tool_call_id=event.tool_call_id, tool_call_id=event.tool_call_id,
kind="execute", kind=resolve_kind(event.tool_name),
raw_input=event.args.model_dump_json(), raw_input=event.args.model_dump_json(),
field_meta={"tool_name": event.tool_name},
) )
@classmethod @classmethod
@ -140,4 +145,14 @@ class Bash(CoreBashTool, BaseAcpTool[AcpBashState]):
session_update="tool_call_update", session_update="tool_call_update",
tool_call_id=event.tool_call_id, tool_call_id=event.tool_call_id,
status="failed" if event.error else "completed", status="failed" if event.error else "completed",
content=[
ContentToolCallContent(
type="content",
content=TextContentBlock(
type="text", text=cls.get_result_display(event).message
),
)
],
kind=resolve_kind(event.tool_name),
field_meta={"tool_name": event.tool_name},
) )

View file

@ -0,0 +1,78 @@
from __future__ import annotations
from pathlib import Path
from acp.helpers import SessionUpdate
from acp.schema import (
ContentToolCallContent,
TextContentBlock,
ToolCallLocation,
ToolCallProgress,
ToolCallStart,
)
from vibe import VIBE_ROOT
from vibe.acp.tools.base import (
ToolCallSessionUpdateProtocol,
ToolResultSessionUpdateProtocol,
)
from vibe.acp.tools.session_update import (
failed_tool_result,
fallback_tool_call,
resolve_kind,
)
from vibe.core.tools.builtins.grep import Grep as CoreGrepTool, GrepArgs, GrepResult
from vibe.core.types import ToolCallEvent, ToolResultEvent
class Grep(
CoreGrepTool, ToolCallSessionUpdateProtocol, ToolResultSessionUpdateProtocol
):
prompt_path = VIBE_ROOT / "core" / "tools" / "builtins" / "prompts" / "grep.md"
@classmethod
def tool_call_session_update(cls, event: ToolCallEvent) -> SessionUpdate | None:
if not isinstance(event.args, GrepArgs):
return fallback_tool_call(event, "grep")
search_path = str(Path(event.args.path).resolve())
return ToolCallStart(
session_update="tool_call",
title=cls.get_call_display(event).summary,
tool_call_id=event.tool_call_id,
kind=resolve_kind(event.tool_name),
raw_input=event.args.model_dump_json(),
locations=[ToolCallLocation(path=search_path)],
field_meta={"tool_name": event.tool_name, "query": event.args.pattern},
)
@classmethod
def tool_result_session_update(cls, event: ToolResultEvent) -> SessionUpdate | None:
if failure := failed_tool_result(event, GrepResult):
return failure
result = event.result
assert isinstance(result, GrepResult)
locations = [
ToolCallLocation(path=m.path, line=m.line) for m in result.parsed_matches
]
return ToolCallProgress(
session_update="tool_call_update",
tool_call_id=event.tool_call_id,
status="completed",
content=[
ContentToolCallContent(
type="content",
content=TextContentBlock(
type="text", text=cls.get_result_display(event).message
),
)
],
kind=resolve_kind(event.tool_name),
raw_output=result.model_dump_json(),
locations=locations if locations else None,
field_meta={"tool_name": event.tool_name},
)

View file

@ -2,8 +2,27 @@ from __future__ import annotations
from pathlib import Path from pathlib import Path
from acp.helpers import SessionUpdate
from acp.schema import (
ContentToolCallContent,
TextContentBlock,
ToolCallLocation,
ToolCallProgress,
ToolCallStart,
)
from vibe import VIBE_ROOT from vibe import VIBE_ROOT
from vibe.acp.tools.base import AcpToolState, BaseAcpTool from vibe.acp.tools.base import (
AcpToolState,
BaseAcpTool,
ToolCallSessionUpdateProtocol,
ToolResultSessionUpdateProtocol,
)
from vibe.acp.tools.session_update import (
failed_tool_result,
fallback_tool_call,
resolve_kind,
)
from vibe.core.tools.base import ToolError from vibe.core.tools.base import ToolError
from vibe.core.tools.builtins.read_file import ( from vibe.core.tools.builtins.read_file import (
ReadFile as CoreReadFileTool, ReadFile as CoreReadFileTool,
@ -12,6 +31,7 @@ from vibe.core.tools.builtins.read_file import (
ReadFileState, ReadFileState,
_ReadResult, _ReadResult,
) )
from vibe.core.types import ToolCallEvent, ToolResultEvent
ReadFileResult = ReadFileResult ReadFileResult = ReadFileResult
@ -20,7 +40,12 @@ class AcpReadFileState(ReadFileState, AcpToolState):
pass pass
class ReadFile(CoreReadFileTool, BaseAcpTool[AcpReadFileState]): class ReadFile(
CoreReadFileTool,
BaseAcpTool[AcpReadFileState],
ToolCallSessionUpdateProtocol,
ToolResultSessionUpdateProtocol,
):
state: AcpReadFileState state: AcpReadFileState
prompt_path = VIBE_ROOT / "core" / "tools" / "builtins" / "prompts" / "read_file.md" prompt_path = VIBE_ROOT / "core" / "tools" / "builtins" / "prompts" / "read_file.md"
@ -28,6 +53,69 @@ class ReadFile(CoreReadFileTool, BaseAcpTool[AcpReadFileState]):
def _get_tool_state_class(cls) -> type[AcpReadFileState]: def _get_tool_state_class(cls) -> type[AcpReadFileState]:
return AcpReadFileState return AcpReadFileState
@classmethod
def tool_call_session_update(cls, event: ToolCallEvent) -> SessionUpdate | None:
if not isinstance(event.args, ReadFileArgs):
return fallback_tool_call(event, "read_file")
resolved = str(Path(event.args.path).resolve())
return ToolCallStart(
session_update="tool_call",
title=cls.format_call_display(event.args).summary,
tool_call_id=event.tool_call_id,
kind=resolve_kind(event.tool_name),
raw_input=event.args.model_dump_json(),
locations=[
ToolCallLocation(
path=resolved,
field_meta={
"type": "file_range",
"offset": event.args.offset,
"limit": event.args.limit,
},
)
],
field_meta={"tool_name": event.tool_name},
)
@classmethod
def tool_result_session_update(cls, event: ToolResultEvent) -> SessionUpdate | None:
if failure := failed_tool_result(event, ReadFileResult):
return failure
result = event.result
assert isinstance(result, ReadFileResult)
resolved = str(Path(result.path).resolve())
locations = [
ToolCallLocation(
path=resolved,
field_meta={
"type": "file_range",
"offset": result.offset,
"limit": result.lines_read,
},
)
]
return ToolCallProgress(
session_update="tool_call_update",
tool_call_id=event.tool_call_id,
status="completed",
content=[
ContentToolCallContent(
type="content",
content=TextContentBlock(
type="text", text=cls.get_result_display(event).message
),
)
],
kind=resolve_kind(event.tool_name),
raw_output=result.model_dump_json(),
locations=locations,
field_meta={"tool_name": event.tool_name},
)
async def _read_file(self, args: ReadFileArgs, file_path: Path) -> _ReadResult: async def _read_file(self, args: ReadFileArgs, file_path: Path) -> _ReadResult:
client, session_id, _ = self._load_state() client, session_id, _ = self._load_state()

View file

@ -12,6 +12,11 @@ from acp.schema import (
from vibe import VIBE_ROOT from vibe import VIBE_ROOT
from vibe.acp.tools.base import AcpToolState, BaseAcpTool from vibe.acp.tools.base import AcpToolState, BaseAcpTool
from vibe.acp.tools.session_update import (
failed_tool_result,
fallback_tool_call,
resolve_kind,
)
from vibe.core.tools.base import BaseToolState, ToolError from vibe.core.tools.base import BaseToolState, ToolError
from vibe.core.tools.builtins.search_replace import ( from vibe.core.tools.builtins.search_replace import (
SearchReplace as CoreSearchReplaceTool, SearchReplace as CoreSearchReplaceTool,
@ -75,18 +80,10 @@ class SearchReplace(CoreSearchReplaceTool, BaseAcpTool[AcpSearchReplaceState]):
@classmethod @classmethod
def tool_call_session_update(cls, event: ToolCallEvent) -> SessionUpdate | None: def tool_call_session_update(cls, event: ToolCallEvent) -> SessionUpdate | None:
if not isinstance(event.args, SearchReplaceArgs):
return fallback_tool_call(event, "search_replace")
args = event.args args = event.args
if args is None:
return ToolCallStart(
session_update="tool_call",
title="search_replace",
tool_call_id=event.tool_call_id,
kind="edit",
content=None,
raw_input=None,
)
if not isinstance(args, SearchReplaceArgs):
return None
blocks = cls._parse_search_replace_blocks(args.content) blocks = cls._parse_search_replace_blocks(args.content)
@ -94,7 +91,7 @@ class SearchReplace(CoreSearchReplaceTool, BaseAcpTool[AcpSearchReplaceState]):
session_update="tool_call", session_update="tool_call",
title=cls.get_call_display(event).summary, title=cls.get_call_display(event).summary,
tool_call_id=event.tool_call_id, tool_call_id=event.tool_call_id,
kind="edit", kind=resolve_kind(event.tool_name),
content=[ content=[
FileEditToolCallContent( FileEditToolCallContent(
type="diff", type="diff",
@ -104,22 +101,18 @@ class SearchReplace(CoreSearchReplaceTool, BaseAcpTool[AcpSearchReplaceState]):
) )
for block in blocks for block in blocks
], ],
locations=[ToolCallLocation(path=args.file_path)], locations=[ToolCallLocation(path=str(Path(args.file_path).resolve()))],
raw_input=args.model_dump_json(), raw_input=args.model_dump_json(),
field_meta={"tool_name": event.tool_name},
) )
@classmethod @classmethod
def tool_result_session_update(cls, event: ToolResultEvent) -> SessionUpdate | None: def tool_result_session_update(cls, event: ToolResultEvent) -> SessionUpdate | None:
if event.error: if failure := failed_tool_result(event, SearchReplaceResult):
return ToolCallProgress( return failure
session_update="tool_call_update",
tool_call_id=event.tool_call_id,
status="failed",
)
result = event.result result = event.result
if not isinstance(result, SearchReplaceResult): assert isinstance(result, SearchReplaceResult)
return None
blocks = cls._parse_search_replace_blocks(result.content) blocks = cls._parse_search_replace_blocks(result.content)
@ -127,6 +120,7 @@ class SearchReplace(CoreSearchReplaceTool, BaseAcpTool[AcpSearchReplaceState]):
session_update="tool_call_update", session_update="tool_call_update",
tool_call_id=event.tool_call_id, tool_call_id=event.tool_call_id,
status="completed", status="completed",
kind=resolve_kind(event.tool_name),
content=[ content=[
FileEditToolCallContent( FileEditToolCallContent(
type="diff", type="diff",
@ -136,6 +130,7 @@ class SearchReplace(CoreSearchReplaceTool, BaseAcpTool[AcpSearchReplaceState]):
) )
for block in blocks for block in blocks
], ],
locations=[ToolCallLocation(path=result.file)], locations=[ToolCallLocation(path=str(Path(result.file).resolve()))],
raw_output=result.model_dump_json(), raw_output=result.model_dump_json(),
field_meta={"tool_name": event.tool_name},
) )

View file

@ -0,0 +1,79 @@
from __future__ import annotations
from pathlib import Path
from acp.helpers import SessionUpdate
from acp.schema import (
ContentToolCallContent,
TextContentBlock,
ToolCallLocation,
ToolCallProgress,
ToolCallStart,
)
from vibe import VIBE_ROOT
from vibe.acp.tools.base import (
ToolCallSessionUpdateProtocol,
ToolResultSessionUpdateProtocol,
)
from vibe.acp.tools.session_update import (
failed_tool_result,
fallback_tool_call,
resolve_kind,
)
from vibe.core.tools.builtins.skill import (
Skill as CoreSkillTool,
SkillArgs,
SkillResult,
)
from vibe.core.types import ToolCallEvent, ToolResultEvent
class Skill(
CoreSkillTool, ToolCallSessionUpdateProtocol, ToolResultSessionUpdateProtocol
):
prompt_path = VIBE_ROOT / "core" / "tools" / "builtins" / "prompts" / "skill.md"
@classmethod
def tool_call_session_update(cls, event: ToolCallEvent) -> SessionUpdate | None:
if not isinstance(event.args, SkillArgs):
return fallback_tool_call(event, "skill")
return ToolCallStart(
session_update="tool_call",
title=cls.get_call_display(event).summary,
tool_call_id=event.tool_call_id,
kind=resolve_kind(event.tool_name),
raw_input=event.args.model_dump_json(),
field_meta={"tool_name": event.tool_name, "skill_name": event.args.name},
)
@classmethod
def tool_result_session_update(cls, event: ToolResultEvent) -> SessionUpdate | None:
if failure := failed_tool_result(event, SkillResult):
return failure
result = event.result
assert isinstance(result, SkillResult)
locations: list[ToolCallLocation] | None = None
if result.skill_dir:
locations = [ToolCallLocation(path=str(Path(result.skill_dir).resolve()))]
return ToolCallProgress(
session_update="tool_call_update",
tool_call_id=event.tool_call_id,
status="completed",
content=[
ContentToolCallContent(
type="content",
content=TextContentBlock(
type="text", text=cls.get_result_display(event).message
),
)
],
kind=resolve_kind(event.tool_name),
raw_output=result.model_dump_json(),
locations=locations,
field_meta={"tool_name": event.tool_name, "skill_name": result.name},
)

View file

@ -0,0 +1,75 @@
from __future__ import annotations
from acp.helpers import SessionUpdate
from acp.schema import (
ContentToolCallContent,
TextContentBlock,
ToolCallProgress,
ToolCallStart,
)
from vibe import VIBE_ROOT
from vibe.acp.tools.base import (
ToolCallSessionUpdateProtocol,
ToolResultSessionUpdateProtocol,
)
from vibe.acp.tools.session_update import (
failed_tool_result,
fallback_tool_call,
resolve_kind,
)
from vibe.core.tools.builtins.task import Task as CoreTaskTool, TaskArgs, TaskResult
from vibe.core.types import ToolCallEvent, ToolResultEvent
class Task(
CoreTaskTool, ToolCallSessionUpdateProtocol, ToolResultSessionUpdateProtocol
):
prompt_path = VIBE_ROOT / "core" / "tools" / "builtins" / "prompts" / "task.md"
@classmethod
def tool_call_session_update(cls, event: ToolCallEvent) -> SessionUpdate | None:
if not isinstance(event.args, TaskArgs):
return fallback_tool_call(event, "task")
return ToolCallStart(
session_update="tool_call",
title=cls.get_call_display(event).summary,
tool_call_id=event.tool_call_id,
kind=resolve_kind(event.tool_name),
raw_input=event.args.model_dump_json(),
field_meta={
"tool_name": event.tool_name,
"agent": event.args.agent,
"task": event.args.task,
},
)
@classmethod
def tool_result_session_update(cls, event: ToolResultEvent) -> SessionUpdate | None:
if failure := failed_tool_result(event, TaskResult):
return failure
result = event.result
assert isinstance(result, TaskResult)
return ToolCallProgress(
session_update="tool_call_update",
tool_call_id=event.tool_call_id,
status="completed" if result.completed else "failed",
content=[
ContentToolCallContent(
type="content",
content=TextContentBlock(
type="text", text=cls.get_result_display(event).message
),
)
],
kind=resolve_kind(event.tool_name),
raw_output=result.model_dump_json(),
field_meta={
"tool_name": event.tool_name,
"turn_count": result.turns_used,
"response": result.response,
},
)

View file

@ -0,0 +1,85 @@
from __future__ import annotations
from acp.helpers import SessionUpdate
from acp.schema import (
ContentToolCallContent,
TextContentBlock,
ToolCallLocation,
ToolCallProgress,
ToolCallStart,
)
from vibe import VIBE_ROOT
from vibe.acp.tools.base import (
ToolCallSessionUpdateProtocol,
ToolResultSessionUpdateProtocol,
)
from vibe.acp.tools.session_update import (
failed_tool_result,
fallback_tool_call,
resolve_kind,
)
from vibe.core.tools.builtins.webfetch import (
WebFetch as CoreWebFetchTool,
WebFetchArgs,
WebFetchResult,
)
from vibe.core.types import ToolCallEvent, ToolResultEvent
class WebFetch(
CoreWebFetchTool, ToolCallSessionUpdateProtocol, ToolResultSessionUpdateProtocol
):
prompt_path = VIBE_ROOT / "core" / "tools" / "builtins" / "prompts" / "webfetch.md"
@classmethod
def tool_call_session_update(cls, event: ToolCallEvent) -> SessionUpdate | None:
if not isinstance(event.args, WebFetchArgs):
return fallback_tool_call(event, "web_fetch")
url = cls._normalize_url(event.args.url)
return ToolCallStart(
session_update="tool_call",
title=cls.get_call_display(event).summary,
tool_call_id=event.tool_call_id,
kind=resolve_kind(event.tool_name),
raw_input=event.args.model_dump_json(),
locations=[ToolCallLocation(path=url, field_meta={"type": "url"})],
field_meta={"tool_name": event.tool_name},
)
@classmethod
def tool_result_session_update(cls, event: ToolResultEvent) -> SessionUpdate | None:
if failure := failed_tool_result(event, WebFetchResult):
return failure
result = event.result
assert isinstance(result, WebFetchResult)
return ToolCallProgress(
session_update="tool_call_update",
tool_call_id=event.tool_call_id,
status="completed",
content=[
ContentToolCallContent(
type="content",
content=TextContentBlock(
type="text", text=cls.get_result_display(event).message
),
)
],
kind=resolve_kind(event.tool_name),
raw_output=result.model_dump_json(),
locations=[
ToolCallLocation(
path=result.url,
field_meta={
"type": "url",
"char_count": len(result.content),
"truncated": result.was_truncated,
},
)
],
field_meta={"tool_name": event.tool_name},
)

View file

@ -0,0 +1,80 @@
from __future__ import annotations
from acp.helpers import SessionUpdate
from acp.schema import (
ContentToolCallContent,
TextContentBlock,
ToolCallLocation,
ToolCallProgress,
ToolCallStart,
)
from vibe import VIBE_ROOT
from vibe.acp.tools.base import (
ToolCallSessionUpdateProtocol,
ToolResultSessionUpdateProtocol,
)
from vibe.acp.tools.session_update import (
failed_tool_result,
fallback_tool_call,
resolve_kind,
)
from vibe.core.tools.builtins.websearch import (
WebSearch as CoreWebSearchTool,
WebSearchArgs,
WebSearchResult,
)
from vibe.core.types import ToolCallEvent, ToolResultEvent
class WebSearch(
CoreWebSearchTool, ToolCallSessionUpdateProtocol, ToolResultSessionUpdateProtocol
):
prompt_path = VIBE_ROOT / "core" / "tools" / "builtins" / "prompts" / "websearch.md"
@classmethod
def tool_call_session_update(cls, event: ToolCallEvent) -> SessionUpdate | None:
if not isinstance(event.args, WebSearchArgs):
return fallback_tool_call(event, "web_search")
return ToolCallStart(
session_update="tool_call",
title=cls.get_call_display(event).summary,
tool_call_id=event.tool_call_id,
kind=resolve_kind(event.tool_name),
raw_input=event.args.model_dump_json(),
field_meta={"tool_name": event.tool_name, "query": event.args.query},
)
@classmethod
def tool_result_session_update(cls, event: ToolResultEvent) -> SessionUpdate | None:
if failure := failed_tool_result(event, WebSearchResult):
return failure
result = event.result
assert isinstance(result, WebSearchResult)
locations = [
ToolCallLocation(
path=source.url, field_meta={"type": "url", "title": source.title}
)
for source in result.sources
]
return ToolCallProgress(
session_update="tool_call_update",
tool_call_id=event.tool_call_id,
status="completed",
content=[
ContentToolCallContent(
type="content",
content=TextContentBlock(
type="text", text=cls.get_result_display(event).message
),
)
],
kind=resolve_kind(event.tool_name),
raw_output=result.model_dump_json(),
locations=locations if locations else None,
field_meta={"tool_name": event.tool_name},
)

View file

@ -12,6 +12,11 @@ from acp.schema import (
from vibe import VIBE_ROOT from vibe import VIBE_ROOT
from vibe.acp.tools.base import AcpToolState, BaseAcpTool from vibe.acp.tools.base import AcpToolState, BaseAcpTool
from vibe.acp.tools.session_update import (
failed_tool_result,
fallback_tool_call,
resolve_kind,
)
from vibe.core.tools.base import BaseToolState, ToolError from vibe.core.tools.base import BaseToolState, ToolError
from vibe.core.tools.builtins.write_file import ( from vibe.core.tools.builtins.write_file import (
WriteFile as CoreWriteFileTool, WriteFile as CoreWriteFileTool,
@ -49,50 +54,40 @@ class WriteFile(CoreWriteFileTool, BaseAcpTool[AcpWriteFileState]):
@classmethod @classmethod
def tool_call_session_update(cls, event: ToolCallEvent) -> SessionUpdate | None: def tool_call_session_update(cls, event: ToolCallEvent) -> SessionUpdate | None:
args = event.args if not isinstance(event.args, WriteFileArgs):
if args is None: return fallback_tool_call(event, "write_file")
return ToolCallStart(
session_update="tool_call",
title="write_file",
tool_call_id=event.tool_call_id,
kind="edit",
content=None,
raw_input=None,
)
if not isinstance(args, WriteFileArgs):
return None
return ToolCallStart( return ToolCallStart(
session_update="tool_call", session_update="tool_call",
title=cls.get_call_display(event).summary, title=cls.format_call_display(event.args).summary,
tool_call_id=event.tool_call_id, tool_call_id=event.tool_call_id,
kind="edit", kind=resolve_kind(event.tool_name),
content=[ content=[
FileEditToolCallContent( FileEditToolCallContent(
type="diff", path=args.path, old_text=None, new_text=args.content type="diff",
path=event.args.path,
old_text=None,
new_text=event.args.content,
) )
], ],
locations=[ToolCallLocation(path=args.path)], locations=[ToolCallLocation(path=str(Path(event.args.path).resolve()))],
raw_input=args.model_dump_json(), raw_input=event.args.model_dump_json(),
field_meta={"tool_name": event.tool_name},
) )
@classmethod @classmethod
def tool_result_session_update(cls, event: ToolResultEvent) -> SessionUpdate | None: def tool_result_session_update(cls, event: ToolResultEvent) -> SessionUpdate | None:
if event.error: if failure := failed_tool_result(event, WriteFileResult):
return ToolCallProgress( return failure
session_update="tool_call_update",
tool_call_id=event.tool_call_id,
status="failed",
)
result = event.result result = event.result
if not isinstance(result, WriteFileResult): assert isinstance(result, WriteFileResult)
return None
return ToolCallProgress( return ToolCallProgress(
session_update="tool_call_update", session_update="tool_call_update",
tool_call_id=event.tool_call_id, tool_call_id=event.tool_call_id,
status="completed", status="completed",
kind=resolve_kind(event.tool_name),
content=[ content=[
FileEditToolCallContent( FileEditToolCallContent(
type="diff", type="diff",
@ -101,6 +96,7 @@ class WriteFile(CoreWriteFileTool, BaseAcpTool[AcpWriteFileState]):
new_text=result.content, new_text=result.content,
) )
], ],
locations=[ToolCallLocation(path=result.path)], locations=[ToolCallLocation(path=str(Path(result.path).resolve()))],
raw_output=result.model_dump_json(), raw_output=result.model_dump_json(),
field_meta={"tool_name": event.tool_name},
) )

View file

@ -8,6 +8,7 @@ from acp.schema import (
ToolCallStart, ToolCallStart,
ToolKind, ToolKind,
) )
from pydantic import BaseModel
from vibe.acp.tools.base import ( from vibe.acp.tools.base import (
ToolCallSessionUpdateProtocol, ToolCallSessionUpdateProtocol,
@ -17,16 +18,75 @@ from vibe.core.tools.ui import ToolUIDataAdapter
from vibe.core.types import ToolCallEvent, ToolResultEvent from vibe.core.types import ToolCallEvent, ToolResultEvent
from vibe.core.utils import TaggedText, is_user_cancellation_event from vibe.core.utils import TaggedText, is_user_cancellation_event
TOOL_KIND: dict[str, ToolKind] = {
"grep": "search", def _cancellation_raw_output(event: ToolResultEvent) -> str | None:
if event.skip_reason:
return TaggedText.from_string(event.skip_reason).message
if event.error:
return TaggedText.from_string(event.error).message
return None
TOOL_KIND_MAP: dict[str, ToolKind] = {
"read_file": "read", "read_file": "read",
# Right now, jetbrains implementation of "edit" tool kind is broken "grep": "search",
# Leading to the tool not appearing in the chat "web_search": "search",
# "write_file": "edit", "web_fetch": "fetch",
# "search_replace": "edit", "write_file": "edit",
"search_replace": "edit",
"bash": "execute",
"skill": "read",
} }
def resolve_kind(tool_name: str) -> ToolKind:
return TOOL_KIND_MAP.get(tool_name, "other")
def failed_tool_result(
event: ToolResultEvent, expected_type: type[BaseModel]
) -> ToolCallProgress | None:
"""Return a failed ToolCallProgress if event is cancelled or has unexpected result type.
Returns None when the result is valid (caller handles the success path).
"""
kind = resolve_kind(event.tool_name)
if is_user_cancellation_event(event):
return ToolCallProgress(
session_update="tool_call_update",
tool_call_id=event.tool_call_id,
status="failed",
kind=kind,
raw_output=_cancellation_raw_output(event),
field_meta={"tool_name": event.tool_name},
)
if not isinstance(event.result, expected_type):
return ToolCallProgress(
session_update="tool_call_update",
tool_call_id=event.tool_call_id,
status="failed",
kind=kind,
raw_output=event.error or event.skip_reason,
field_meta={"tool_name": event.tool_name},
)
return None
def fallback_tool_call(event: ToolCallEvent, title: str) -> ToolCallStart:
"""Default ToolCallStart when args are None or an unexpected type."""
return ToolCallStart(
session_update="tool_call",
title=title,
tool_call_id=event.tool_call_id,
kind=resolve_kind(event.tool_name),
raw_input=None,
field_meta={"tool_name": event.tool_name},
)
def tool_call_session_update(event: ToolCallEvent) -> SessionUpdate | None: def tool_call_session_update(event: ToolCallEvent) -> SessionUpdate | None:
if issubclass(event.tool_class, ToolCallSessionUpdateProtocol): if issubclass(event.tool_class, ToolCallSessionUpdateProtocol):
return event.tool_class.tool_call_session_update(event) return event.tool_class.tool_call_session_update(event)
@ -49,8 +109,9 @@ def tool_call_session_update(event: ToolCallEvent) -> SessionUpdate | None:
title=display.summary, title=display.summary,
content=content, content=content,
tool_call_id=event.tool_call_id, tool_call_id=event.tool_call_id,
kind=TOOL_KIND.get(event.tool_name, "other"), kind=resolve_kind(event.tool_name),
raw_input=event.args.model_dump_json() if event.args else None, raw_input=event.args.model_dump_json() if event.args else None,
field_meta={"tool_name": event.tool_name},
) )
@ -116,6 +177,8 @@ def tool_result_session_update(event: ToolResultEvent) -> SessionUpdate | None:
session_update="tool_call_update", session_update="tool_call_update",
tool_call_id=event.tool_call_id, tool_call_id=event.tool_call_id,
status=tool_status, status=tool_status,
kind=resolve_kind(event.tool_name),
raw_output=raw_output, raw_output=raw_output,
content=content, content=content,
field_meta={"tool_name": event.tool_name},
) )

View file

@ -305,6 +305,7 @@ def create_tool_call_replay(
tool_call_id=tool_call_id, tool_call_id=tool_call_id,
kind="other", kind="other",
raw_input=arguments, raw_input=arguments,
field_meta={"tool_name": tool_name},
) )

View file

@ -57,6 +57,7 @@ from vibe.cli.textual_ui.widgets.chat_input import ChatInputContainer
from vibe.cli.textual_ui.widgets.chat_input.text_area import ChatTextArea from vibe.cli.textual_ui.widgets.chat_input.text_area import ChatTextArea
from vibe.cli.textual_ui.widgets.compact import CompactMessage from vibe.cli.textual_ui.widgets.compact import CompactMessage
from vibe.cli.textual_ui.widgets.config_app import ConfigApp from vibe.cli.textual_ui.widgets.config_app import ConfigApp
from vibe.cli.textual_ui.widgets.connector_auth_app import ConnectorAuthApp
from vibe.cli.textual_ui.widgets.context_progress import ContextProgress, TokenState from vibe.cli.textual_ui.widgets.context_progress import ContextProgress, TokenState
from vibe.cli.textual_ui.widgets.debug_console import DebugConsole from vibe.cli.textual_ui.widgets.debug_console import DebugConsole
from vibe.cli.textual_ui.widgets.feedback_bar import FeedbackBar from vibe.cli.textual_ui.widgets.feedback_bar import FeedbackBar
@ -198,6 +199,7 @@ class BottomApp(StrEnum):
Approval = auto() Approval = auto()
Config = auto() Config = auto()
ConnectorAuth = auto()
Input = auto() Input = auto()
MCP = auto() MCP = auto()
ModelPicker = auto() ModelPicker = auto()
@ -808,6 +810,27 @@ class VibeApp(App): # noqa: PLR0904
self.query_one(MCPApp).refresh_index() self.query_one(MCPApp).refresh_index()
self._refresh_banner() self._refresh_banner()
async def on_mcpapp_connector_auth_requested(
self, message: MCPApp.ConnectorAuthRequested
) -> None:
await self._switch_to_input_app()
await self._switch_from_input(
ConnectorAuthApp(
connector_name=message.connector_name,
connector_registry=message.connector_registry,
tool_manager=message.tool_manager,
)
)
async def on_connector_auth_app_connector_auth_closed(
self, message: ConnectorAuthApp.ConnectorAuthClosed
) -> None:
if message.refreshed:
await self.agent_loop.refresh_system_prompt()
self._refresh_banner()
await self._switch_to_input_app()
await self._show_mcp(cmd_args=message.connector_name)
async def on_proxy_setup_app_proxy_setup_closed( async def on_proxy_setup_app_proxy_setup_closed(
self, message: ProxySetupApp.ProxySetupClosed self, message: ProxySetupApp.ProxySetupClosed
) -> None: ) -> None:
@ -1336,9 +1359,9 @@ class VibeApp(App): # noqa: PLR0904
teleport_msg.set_status("Teleporting...") teleport_msg.set_status("Teleporting...")
case TeleportWaitingForGitHubEvent(): case TeleportWaitingForGitHubEvent():
teleport_msg.set_status("Connecting to GitHub...") teleport_msg.set_status("Connecting to GitHub...")
case TeleportAuthRequiredEvent(oauth_url=url): case TeleportAuthRequiredEvent(oauth_url=url, message=msg):
webbrowser.open(url) webbrowser.open(url)
teleport_msg.set_status("Authorizing GitHub...") teleport_msg.set_status(msg or "Authorizing GitHub...")
case TeleportAuthCompleteEvent(): case TeleportAuthCompleteEvent():
teleport_msg.set_status("GitHub authorized") teleport_msg.set_status("GitHub authorized")
case TeleportFetchingUrlEvent(): case TeleportFetchingUrlEvent():
@ -2059,6 +2082,8 @@ class VibeApp(App): # noqa: PLR0904
self.query_one(SessionPickerApp).focus() self.query_one(SessionPickerApp).focus()
case BottomApp.MCP: case BottomApp.MCP:
self.query_one(MCPApp).focus() self.query_one(MCPApp).focus()
case BottomApp.ConnectorAuth:
self.query_one(ConnectorAuthApp).focus()
case BottomApp.Rewind: case BottomApp.Rewind:
self.query_one(RewindApp).focus() self.query_one(RewindApp).focus()
case BottomApp.Voice: case BottomApp.Voice:
@ -2335,7 +2360,7 @@ class VibeApp(App): # noqa: PLR0904
self.run_worker(self._interrupt_agent_loop(), exclusive=False) self.run_worker(self._interrupt_agent_loop(), exclusive=False)
def _handle_bottom_app_close_escape( def _handle_bottom_app_close_escape(
self, widget_type: type[MCPApp] | type[ProxySetupApp] self, widget_type: type[MCPApp] | type[ProxySetupApp] | type[ConnectorAuthApp]
) -> None: ) -> None:
try: try:
self.query_one(widget_type).action_close() self.query_one(widget_type).action_close()
@ -2350,6 +2375,8 @@ class VibeApp(App): # noqa: PLR0904
self._handle_voice_app_escape() self._handle_voice_app_escape()
elif self._current_bottom_app == BottomApp.MCP: elif self._current_bottom_app == BottomApp.MCP:
self._handle_bottom_app_close_escape(MCPApp) self._handle_bottom_app_close_escape(MCPApp)
elif self._current_bottom_app == BottomApp.ConnectorAuth:
self._handle_bottom_app_close_escape(ConnectorAuthApp)
elif self._current_bottom_app == BottomApp.ProxySetup: elif self._current_bottom_app == BottomApp.ProxySetup:
self._handle_bottom_app_close_escape(ProxySetupApp) self._handle_bottom_app_close_escape(ProxySetupApp)
elif self._current_bottom_app == BottomApp.Approval: elif self._current_bottom_app == BottomApp.Approval:

View file

@ -691,7 +691,7 @@ StatusMessage {
} }
#config-app, #voice-app, #mcp-app { #config-app, #voice-app, #mcp-app, #connectorauth-app {
width: 100%; width: 100%;
height: auto; height: auto;
background: transparent; background: transparent;
@ -700,7 +700,7 @@ StatusMessage {
margin: 0; margin: 0;
} }
#config-content, #voice-content, #mcp-content { #config-content, #voice-content, #mcp-content, #connectorauth-content {
width: 100%; width: 100%;
height: auto; height: auto;
} }
@ -711,16 +711,20 @@ StatusMessage {
color: ansi_blue; color: ansi_blue;
} }
#config-options, #mcp-options { #config-options, #mcp-options, #connectorauth-options {
width: 100%; width: 100%;
max-height: 50vh; max-height: 50vh;
border: none; border: none;
} }
#config-options:focus, #mcp-options:focus { #config-options:focus, #mcp-options:focus, #connectorauth-options:focus {
border: none; border: none;
} }
#connectorauth-detail {
margin: 1 0;
}
.settings-help { .settings-help {
height: auto; height: auto;
color: ansi_bright_black; color: ansi_bright_black;

View file

@ -0,0 +1,227 @@
from __future__ import annotations
from enum import StrEnum, auto
from typing import TYPE_CHECKING, ClassVar
import webbrowser
from rich.text import Text
from textual.app import ComposeResult
from textual.binding import Binding, BindingType
from textual.containers import Container, Vertical
from textual.events import DescendantBlur
from textual.message import Message
from textual.widgets import OptionList
from textual.widgets.option_list import Option
from textual.worker import Worker
from vibe.cli.clipboard import copy_text_to_clipboard
from vibe.cli.textual_ui.widgets.no_markup_static import NoMarkupStatic
from vibe.core.tools.connectors import ConnectorRegistry
if TYPE_CHECKING:
from vibe.core.tools.manager import ToolManager
_HELP = "Backspace Back"
_OPTION_PADDING = " "
class _AuthOptionId(StrEnum):
OPEN = auto()
COPY = auto()
SHOW = auto()
class ConnectorAuthApp(Container):
"""Bottom-panel app for authenticating a workspace connector."""
can_focus_children = True
BINDINGS: ClassVar[list[BindingType]] = [
Binding("escape", "close", "Close", show=False),
Binding("backspace", "close", "Back", show=False),
Binding("r", "refresh", "Refresh", show=False),
]
class ConnectorAuthClosed(Message):
def __init__(
self, *, refreshed: bool = False, connector_name: str = ""
) -> None:
super().__init__()
self.refreshed = refreshed
self.connector_name = connector_name
def __init__(
self,
connector_name: str,
connector_registry: ConnectorRegistry,
tool_manager: ToolManager,
) -> None:
super().__init__(id="connectorauth-app")
self._connector_name = connector_name
self._connector_registry = connector_registry
self._tool_manager = tool_manager
self._auth_url: str | None = None
self._auth_url_visible = False
self._status_message: str | None = None
def compose(self) -> ComposeResult:
with Vertical(id="connectorauth-content"):
yield NoMarkupStatic("", id="connectorauth-title", classes="settings-title")
yield NoMarkupStatic("")
yield OptionList(id="connectorauth-options")
yield NoMarkupStatic("", id="connectorauth-detail")
yield NoMarkupStatic("", id="connectorauth-help", classes="settings-help")
def on_mount(self) -> None:
self.query_one("#connectorauth-title", NoMarkupStatic).update(
f"Connector: {self._connector_name}"
)
option_list = self.query_one(OptionList)
option_list.add_option(Option("Fetching authentication info...", disabled=True))
self._set_help_text(_HELP)
option_list.focus()
self.run_worker(self._fetch_auth_url(), exclusive=True, group="auth_url")
def on_descendant_blur(self, _event: DescendantBlur) -> None:
self.query_one(OptionList).focus()
def on_option_list_option_selected(self, event: OptionList.OptionSelected) -> None:
option_id = event.option.id or ""
if option_id == _AuthOptionId.OPEN:
self._open_browser()
elif option_id == _AuthOptionId.COPY:
self._copy_url()
elif option_id == _AuthOptionId.SHOW:
self._toggle_url()
def action_close(self) -> None:
self.post_message(self.ConnectorAuthClosed())
async def action_refresh(self) -> None:
self._status_message = "Refreshing connector..."
self._set_help_text(_HELP)
self.run_worker(
self._refresh_connector(), exclusive=True, group="connector_refresh"
)
# ── workers ──────────────────────────────────────────────────────
async def _fetch_auth_url(self) -> str | None:
return await self._connector_registry.get_auth_url(self._connector_name)
async def _refresh_connector(self) -> int:
"""Refresh connector tools. Returns the number of tools discovered."""
from vibe.core.tools.manager import ToolManager
new_tools = await self._connector_registry.refresh_connector_async(
self._connector_name
)
if isinstance(self._tool_manager, ToolManager):
await self._tool_manager.integrate_connectors_async()
return len(new_tools)
def on_worker_state_changed(self, event: Worker.StateChanged) -> None:
if event.worker.group == "auth_url" and event.worker.is_finished:
self._on_auth_url_fetched(event.worker.result)
elif event.worker.group == "connector_refresh" and event.worker.is_finished:
tool_count = (
event.worker.result if isinstance(event.worker.result, int) else 0
)
self._on_connector_refreshed(tool_count)
# ── auth UI ──────────────────────────────────────────────────────
def _on_auth_url_fetched(self, result: object) -> None:
option_list = self.query_one(OptionList)
option_list.clear_options()
auth_url = result if isinstance(result, str) else None
if auth_url:
self._auth_url = auth_url
option_list.add_option(
Option(
Text("This connector requires authentication", no_wrap=True),
disabled=True,
)
)
option_list.add_option(Option("", disabled=True))
option_list.add_option(
Option(
Text(
f"{_OPTION_PADDING}Press enter to open auth in your browser",
no_wrap=True,
),
id=_AuthOptionId.OPEN,
)
)
option_list.add_option(
Option(
Text(f"{_OPTION_PADDING}Copy URL to clipboard", no_wrap=True),
id=_AuthOptionId.COPY,
)
)
option_list.add_option(
Option(
Text(f"{_OPTION_PADDING}Manually show the URL", no_wrap=True),
id=_AuthOptionId.SHOW,
)
)
option_list.highlighted = option_list.get_option_index(_AuthOptionId.OPEN)
self._update_detail_text()
else:
self.query_one("#connectorauth-detail", NoMarkupStatic).update("")
option_list.add_option(
Option("This connector does not provide authentication", disabled=True)
)
self._set_help_text(_HELP)
def _on_connector_refreshed(self, tool_count: int) -> None:
if tool_count > 0:
self._status_message = f"{tool_count} tools discovered."
self.post_message(
self.ConnectorAuthClosed(
refreshed=True, connector_name=self._connector_name
)
)
else:
self._status_message = (
"No tools discovered. Authentication may still be pending, "
"try again in a moment."
)
self._set_help_text(_HELP)
# ── actions ──────────────────────────────────────────────────────
def _open_browser(self) -> None:
if self._auth_url is None:
return
webbrowser.open(self._auth_url)
self._status_message = "Opened in browser."
self._set_help_text(_HELP)
def _copy_url(self) -> None:
if self._auth_url is None:
return
copy_text_to_clipboard(
self.app, self._auth_url, success_message="Auth URL copied to clipboard"
)
def _toggle_url(self) -> None:
if self._auth_url is None:
return
self._auth_url_visible = not self._auth_url_visible
self._update_detail_text()
# ── helpers ──────────────────────────────────────────────────────
def _update_detail_text(self) -> None:
detail = self.query_one("#connectorauth-detail", NoMarkupStatic)
parts: list[str] = []
if self._auth_url_visible and self._auth_url:
parts.append(self._auth_url)
parts.append("")
parts.append("Once authenticated, press R to refresh")
detail.update("\n".join(parts))
def _set_help_text(self, text: str) -> None:
if self._status_message:
text = f"{self._status_message} {text}"
self.query_one("#connectorauth-help", NoMarkupStatic).update(text)

View file

@ -62,9 +62,12 @@ def collect_mcp_tool_index(
return MCPToolIndex(server_tools, connector_tools, enabled_tools=available) return MCPToolIndex(server_tools, connector_tools, enabled_tools=available)
_LIST_VIEW_HELP = ( _LIST_VIEW_HELP_TOOLS = (
"↑↓ Navigate Enter Show tools D Disable E Enable R Refresh Esc Close" "↑↓ Navigate Enter Show tools D Disable E Enable R Refresh Esc Close"
) )
_LIST_VIEW_HELP_AUTH = (
"↑↓ Navigate Enter Authenticate D Disable E Enable R Refresh Esc Close"
)
_DETAIL_VIEW_HELP = ( _DETAIL_VIEW_HELP = (
"↑↓ Navigate D Disable E Enable Backspace Back R Refresh Esc Close" "↑↓ Navigate D Disable E Enable Backspace Back R Refresh Esc Close"
) )
@ -99,6 +102,20 @@ class MCPApp(Container):
self.disabled = disabled self.disabled = disabled
self.tool_name = tool_name self.tool_name = tool_name
class ConnectorAuthRequested(Message):
"""Posted when a disconnected connector needs authentication."""
def __init__(
self,
connector_name: str,
connector_registry: ConnectorRegistry,
tool_manager: ToolManager,
) -> None:
super().__init__()
self.connector_name = connector_name
self.connector_registry = connector_registry
self.tool_manager = tool_manager
def __init__( def __init__(
self, self,
mcp_servers: Sequence[MCPServer], mcp_servers: Sequence[MCPServer],
@ -134,7 +151,6 @@ class MCPApp(Container):
yield NoMarkupStatic("", id="mcp-title", classes="settings-title") yield NoMarkupStatic("", id="mcp-title", classes="settings-title")
yield NoMarkupStatic("") yield NoMarkupStatic("")
yield OptionList(id="mcp-options") yield OptionList(id="mcp-options")
yield NoMarkupStatic("")
yield NoMarkupStatic("", id="mcp-help", classes="settings-help") yield NoMarkupStatic("", id="mcp-help", classes="settings-help")
def on_mount(self) -> None: def on_mount(self) -> None:
@ -175,6 +191,9 @@ class MCPApp(Container):
# it are disabled headers, scroll to top so the header stays visible. # it are disabled headers, scroll to top so the header stays visible.
if all(option_list.get_option_at_index(i).disabled for i in range(highlighted)): if all(option_list.get_option_at_index(i).disabled for i in range(highlighted)):
option_list.scroll_to(y=0, animate=False, force=True, immediate=True) option_list.scroll_to(y=0, animate=False, force=True, immediate=True)
# Update help text based on whether highlighted connector needs auth.
if self._viewing_server is None:
self._set_help_text(self._list_help_for_option(event.option))
def action_back(self) -> None: def action_back(self) -> None:
if self._refreshing: if self._refreshing:
@ -192,7 +211,7 @@ class MCPApp(Container):
return return
self._status_message = "Refreshing..." self._status_message = "Refreshing..."
help = _DETAIL_VIEW_HELP if self._viewing_server else _LIST_VIEW_HELP help = _DETAIL_VIEW_HELP if self._viewing_server else _LIST_VIEW_HELP_TOOLS
self._set_help_text(help) self._set_help_text(help)
self._refreshing = True self._refreshing = True
@ -212,6 +231,15 @@ class MCPApp(Container):
self._status_message = result if isinstance(result, str) else "Refreshed." self._status_message = result if isinstance(result, str) else "Refreshed."
self.refresh_index() self.refresh_index()
def _list_help_for_option(self, option: Option) -> str:
"""Return the appropriate list-view help text for the given option."""
option_id = option.id or ""
if option_id.startswith("connector:") and self._connector_registry:
name = option_id.removeprefix("connector:")
if not self._connector_registry.is_connected(name):
return _LIST_VIEW_HELP_AUTH
return _LIST_VIEW_HELP_TOOLS
def _set_help_text(self, text: str) -> None: def _set_help_text(self, text: str) -> None:
if self._status_message: if self._status_message:
text = f"{self._status_message} {text}" text = f"{self._status_message} {text}"
@ -385,7 +413,7 @@ class MCPApp(Container):
has_connectors = connectors_enabled() and bool(self._connector_names) has_connectors = connectors_enabled() and bool(self._connector_names)
title = "MCP Servers & Connectors" if has_connectors else "MCP Servers" title = "MCP Servers & Connectors" if has_connectors else "MCP Servers"
self.query_one("#mcp-title", NoMarkupStatic).update(title) self.query_one("#mcp-title", NoMarkupStatic).update(title)
self._set_help_text(_LIST_VIEW_HELP) self._set_help_text(_LIST_VIEW_HELP_TOOLS)
has_servers = bool(self._mcp_servers) has_servers = bool(self._mcp_servers)
@ -495,9 +523,22 @@ class MCPApp(Container):
tools_source = index.connector_tools if is_connector else index.server_tools tools_source = index.connector_tools if is_connector else index.server_tools
all_tools = sorted(tools_source.get(server_name, []), key=lambda t: t[0]) all_tools = sorted(tools_source.get(server_name, []), key=lambda t: t[0])
if not all_tools: if not all_tools:
option_list.add_option( if (
Option("No tools discovered for this server", disabled=True) is_connector
) and self._connector_registry
and not self._connector_registry.is_connected(server_name)
):
self.post_message(
self.ConnectorAuthRequested(
connector_name=server_name,
connector_registry=self._connector_registry,
tool_manager=self._tool_manager,
)
)
else:
option_list.add_option(
Option("No tools discovered for this server", disabled=True)
)
return return
for tool_name, cls in all_tools: for tool_name, cls in all_tools:
is_tool_enabled = tool_name in index.enabled_tools is_tool_enabled = tool_name in index.enabled_tools

View file

@ -727,10 +727,9 @@ class AgentLoop:
self, provider: ProviderConfig | None = None self, provider: ProviderConfig | None = None
) -> dict[str, str]: ) -> dict[str, str]:
provider = self.config.get_active_provider() if provider is None else provider provider = self.config.get_active_provider() if provider is None else provider
headers: dict[str, str] = { headers: dict[str, str] = {**provider.extra_headers}
"user-agent": get_user_agent(provider.backend), headers["user-agent"] = get_user_agent(provider.backend)
"x-affinity": self.session_id, headers["x-affinity"] = self.session_id
}
return headers return headers
async def _conversation_loop( async def _conversation_loop(
@ -1423,6 +1422,7 @@ class AgentLoop:
self.session_logger.reset_session( self.session_logger.reset_session(
self.session_id, parent_session_id=old_session_id self.session_id, parent_session_id=old_session_id
) )
self.emit_new_session_telemetry()
async def fork(self, message_id: str | None = None) -> AgentLoop: async def fork(self, message_id: str | None = None) -> AgentLoop:
messages = self._messages_for_fork(message_id) messages = self._messages_for_fork(message_id)

View file

@ -41,6 +41,13 @@ from vibe.core.config.layer import (
TrustResolutionError, TrustResolutionError,
UntrustedLayerError, UntrustedLayerError,
) )
from vibe.core.config.patch import (
AppendToList,
DeleteField,
PatchOp,
RemoveFromList,
SetField,
)
from vibe.core.config.schema import ( from vibe.core.config.schema import (
DuplicateMergeMetadataError, DuplicateMergeMetadataError,
MergeFieldMetadata, MergeFieldMetadata,
@ -60,9 +67,11 @@ __all__ = [
"DEFAULT_TTS_MODELS", "DEFAULT_TTS_MODELS",
"DEFAULT_TTS_PROVIDERS", "DEFAULT_TTS_PROVIDERS",
"THINKING_LEVELS", "THINKING_LEVELS",
"AppendToList",
"ConfigLayer", "ConfigLayer",
"ConfigLayerError", "ConfigLayerError",
"ConnectorConfig", "ConnectorConfig",
"DeleteField",
"DuplicateMergeMetadataError", "DuplicateMergeMetadataError",
"EmptyLayerError", "EmptyLayerError",
"LayerImplementationError", "LayerImplementationError",
@ -75,10 +84,13 @@ __all__ = [
"MissingPromptFileError", "MissingPromptFileError",
"ModelConfig", "ModelConfig",
"OtelSpanExporterConfig", "OtelSpanExporterConfig",
"PatchOp",
"ProjectContextConfig", "ProjectContextConfig",
"ProviderConfig", "ProviderConfig",
"RawConfig", "RawConfig",
"RemoveFromList",
"SessionLoggingConfig", "SessionLoggingConfig",
"SetField",
"TTSClient", "TTSClient",
"TTSModelConfig", "TTSModelConfig",
"TTSProviderConfig", "TTSProviderConfig",

View file

@ -173,6 +173,7 @@ class ProviderConfig(BaseModel):
reasoning_field_name: str = "reasoning_content" reasoning_field_name: str = "reasoning_content"
project_id: str = "" project_id: str = ""
region: str = "" region: str = ""
extra_headers: dict[str, str] = Field(default_factory=dict)
def _is_legacy_mistral_provider_without_backend(self) -> bool: def _is_legacy_mistral_provider_without_backend(self) -> bool:
return ( return (
@ -434,9 +435,11 @@ DEFAULT_MODELS = [
ModelConfig( ModelConfig(
name="mistral-vibe-cli-latest", name="mistral-vibe-cli-latest",
provider="mistral", provider="mistral",
alias="devstral-2", alias="mistral-medium-3.5",
input_price=0.4, temperature=1.0,
output_price=2.0, input_price=1.5,
output_price=7.5,
thinking="high",
), ),
ModelConfig( ModelConfig(
name="devstral-small-latest", name="devstral-small-latest",
@ -973,14 +976,33 @@ class VibeConfig(BaseSettings):
except (FileNotFoundError, tomllib.TOMLDecodeError, OSError): except (FileNotFoundError, tomllib.TOMLDecodeError, OSError):
return return
changed = False
bash_tools = data.get("tools", {}).get("bash", {}) bash_tools = data.get("tools", {}).get("bash", {})
allowlist = bash_tools.get("allowlist") allowlist = bash_tools.get("allowlist")
if allowlist is None or "find" in allowlist: if allowlist is not None and "find" not in allowlist:
return allowlist.append("find")
allowlist.sort()
changed = True
allowlist.append("find") for model in data.get("models", []):
allowlist.sort() if (
cls.dump_config(data) model.get("name") == "mistral-vibe-cli-latest"
and model.get("alias") == "devstral-2"
):
model["alias"] = "mistral-medium-3.5"
model["temperature"] = 1.0
model["input_price"] = 1.5
model["output_price"] = 7.5
model["thinking"] = "high"
changed = True
if data.get("active_model") == "devstral-2":
data["active_model"] = "mistral-medium-3.5"
changed = True
if changed:
cls.dump_config(data)
@classmethod @classmethod
def load(cls, **overrides: Any) -> VibeConfig: def load(cls, **overrides: Any) -> VibeConfig:

70
vibe/core/config/patch.py Normal file
View file

@ -0,0 +1,70 @@
from __future__ import annotations
from dataclasses import dataclass
from typing import Any
@dataclass(frozen=True, slots=True)
class SetField:
"""Set a top-level or nested field to a value."""
key: str
value: Any
def __post_init__(self) -> None:
_validate_key_path(self.key)
@dataclass(frozen=True, slots=True)
class AppendToList:
"""Append items to a list field."""
key: str
items: tuple[Any, ...]
def __post_init__(self) -> None:
_validate_key_path(self.key)
_validate_tuple_value("AppendToList.items", self.items)
@dataclass(frozen=True, slots=True)
class RemoveFromList:
"""Remove items from a list field by value."""
key: str
values: tuple[Any, ...]
def __post_init__(self) -> None:
_validate_key_path(self.key)
_validate_tuple_value("RemoveFromList.values", self.values)
@dataclass(frozen=True, slots=True)
class DeleteField:
"""Remove a field entirely from the config."""
key: str
def __post_init__(self) -> None:
_validate_key_path(self.key)
PatchOp = SetField | AppendToList | RemoveFromList | DeleteField
def _validate_key_path(key: object) -> None:
if not isinstance(key, str):
raise TypeError(
f"Patch operation key must be a string, got {type(key).__name__}"
)
if not key:
raise ValueError("Patch operation key must not be empty")
if any(not segment for segment in key.split(".")):
raise ValueError(
"Patch operation key must be a dot-separated path without empty segments"
)
def _validate_tuple_value(field_name: str, value: object) -> None:
if not isinstance(value, tuple):
raise TypeError(f"{field_name} must be a tuple, got {type(value).__name__}")

View file

@ -64,8 +64,8 @@ class TextOutputFormatter(OutputFormatter):
self._print("Teleporting...") self._print("Teleporting...")
case TeleportWaitingForGitHubEvent(): case TeleportWaitingForGitHubEvent():
self._print("Connecting to GitHub...") self._print("Connecting to GitHub...")
case TeleportAuthRequiredEvent(oauth_url=url): case TeleportAuthRequiredEvent(oauth_url=url, message=msg):
self._print(f"Open to authorize GitHub: {url}") self._print(msg or f"Open to authorize GitHub: {url}")
case TeleportAuthCompleteEvent(): case TeleportAuthCompleteEvent():
self._print("GitHub authorized") self._print("GitHub authorized")
case TeleportFetchingUrlEvent(): case TeleportFetchingUrlEvent():

View file

@ -57,7 +57,7 @@ environment variables with the `VIBE_` prefix (e.g., `VIBE_ACTIVE_MODEL=local`).
```toml ```toml
# Model selection # Model selection
active_model = "devstral-2" # Model alias to use (see [[models]]) active_model = "mistral-medium-3.5" # Model alias to use (see [[models]])
# UI preferences # UI preferences
vim_keybindings = false vim_keybindings = false
@ -103,6 +103,7 @@ backend = "mistral"
name = "llamacpp" name = "llamacpp"
api_base = "http://127.0.0.1:8080/v1" api_base = "http://127.0.0.1:8080/v1"
api_key_env_var = "" api_key_env_var = ""
extra_headers = { "X-Custom-Header" = "value" } # optional per-provider HTTP headers
``` ```
### Models ### Models
@ -111,11 +112,11 @@ api_key_env_var = ""
[[models]] [[models]]
name = "mistral-vibe-cli-latest" name = "mistral-vibe-cli-latest"
provider = "mistral" provider = "mistral"
alias = "devstral-2" alias = "mistral-medium-3.5"
temperature = 0.2 temperature = 1.0
input_price = 0.4 input_price = 1.5
output_price = 2.0 output_price = 7.5
thinking = "off" # "off", "low", "medium", "high", "max" thinking = "high" # "off", "low", "medium", "high", "max"
auto_compact_threshold = 200000 auto_compact_threshold = 200000
[[models]] [[models]]

View file

@ -188,7 +188,9 @@ class TeleportService:
if not github_data.connected: if not github_data.connected:
if github_data.oauth_url: if github_data.oauth_url:
yield TeleportAuthRequiredEvent(oauth_url=github_data.oauth_url) yield TeleportAuthRequiredEvent(
oauth_url=github_data.oauth_url, message=github_data.error
)
await self._nuage_client.wait_for_github_connection(execution_id) await self._nuage_client.wait_for_github_connection(execution_id)
yield TeleportAuthCompleteEvent() yield TeleportAuthCompleteEvent()

View file

@ -5,6 +5,7 @@ from vibe.core.types import BaseEvent
class TeleportAuthRequiredEvent(BaseEvent): class TeleportAuthRequiredEvent(BaseEvent):
oauth_url: str oauth_url: str
message: str | None = None
class TeleportAuthCompleteEvent(BaseEvent): class TeleportAuthCompleteEvent(BaseEvent):

View file

@ -94,6 +94,43 @@ class GrepArgs(BaseModel):
) )
class GrepMatch(BaseModel):
path: str
line: int | None = None
@classmethod
def from_output_line(cls, raw: str) -> GrepMatch | None:
"""Parse a single grep/rg output line in `file:line:content` format.
Handles Windows drive-letter paths like ``C:\\repo\\file.py:10:match``
by skipping a single-letter first segment.
"""
parts = raw.split(":", 3)
MIN_MATCH_PARTS = 2
if len(parts) < MIN_MATCH_PARTS:
return None
# Windows drive letter: first part is a single letter (e.g. "C")
MIN_WINDOWS_PARTS = 3
is_windows_path = (
len(parts[0]) == 1
and parts[0].isalpha()
and len(parts) >= MIN_WINDOWS_PARTS
)
if is_windows_path:
file_path = f"{parts[0]}:{parts[1]}"
line_str = parts[2]
else:
file_path = parts[0]
line_str = parts[1]
try:
line_num = int(line_str) if line_str else None
except (ValueError, TypeError):
line_num = None
return cls(path=str(Path(file_path).resolve()), line=line_num)
class GrepResult(BaseModel): class GrepResult(BaseModel):
matches: str matches: str
match_count: int match_count: int
@ -101,6 +138,14 @@ class GrepResult(BaseModel):
description="True if output was cut short by max_matches or max_output_bytes." description="True if output was cut short by max_matches or max_output_bytes."
) )
@property
def parsed_matches(self) -> list[GrepMatch]:
results: list[GrepMatch] = []
for line in self.matches.splitlines():
if match := GrepMatch.from_output_line(line):
results.append(match)
return results
class Grep( class Grep(
BaseTool[GrepArgs, GrepResult, GrepToolConfig, BaseToolState], BaseTool[GrepArgs, GrepResult, GrepToolConfig, BaseToolState],

View file

@ -48,6 +48,7 @@ class ReadFileArgs(BaseModel):
class ReadFileResult(BaseModel): class ReadFileResult(BaseModel):
path: str path: str
content: str content: str
offset: int = 0
lines_read: int lines_read: int
was_truncated: bool = Field( was_truncated: bool = Field(
description="True if the reading was stopped due to the max_read_bytes limit." description="True if the reading was stopped due to the max_read_bytes limit."
@ -90,6 +91,7 @@ class ReadFile(
yield ReadFileResult( yield ReadFileResult(
path=str(file_path), path=str(file_path),
content="".join(read_result.lines), content="".join(read_result.lines),
offset=args.offset,
lines_read=len(read_result.lines), lines_read=len(read_result.lines),
was_truncated=read_result.was_truncated, was_truncated=read_result.was_truncated,
) )

View file

@ -220,6 +220,7 @@ class ConnectorRegistry:
self._cache: dict[str, dict[str, type[BaseTool]]] | None = None self._cache: dict[str, dict[str, type[BaseTool]]] | None = None
self._connector_names: list[str] = [] self._connector_names: list[str] = []
self._connector_connected: dict[str, bool] = {} self._connector_connected: dict[str, bool] = {}
self._alias_to_id: dict[str, str] = {}
self._discover_lock = asyncio.Lock() self._discover_lock = asyncio.Lock()
def _get_client(self) -> Mistral: def _get_client(self) -> Mistral:
@ -269,6 +270,7 @@ class ConnectorRegistry:
self._cache = {} self._cache = {}
self._connector_names = [] self._connector_names = []
self._connector_connected = {} self._connector_connected = {}
self._alias_to_id = {}
return {} return {}
# Build results locally to avoid publishing incomplete state. # Build results locally to avoid publishing incomplete state.
@ -324,6 +326,7 @@ class ConnectorRegistry:
# lock will see the completed cache. # lock will see the completed cache.
self._connector_names = connector_names self._connector_names = connector_names
self._connector_connected = connector_connected self._connector_connected = connector_connected
self._alias_to_id = {alias: cid for cid, alias, _ in unique_connectors}
self._cache = cache self._cache = cache
return all_tools return all_tools
@ -411,7 +414,63 @@ class ConnectorRegistry:
def is_connected(self, name: str) -> bool: def is_connected(self, name: str) -> bool:
return self._connector_connected.get(name, False) return self._connector_connected.get(name, False)
def get_connector_id(self, alias: str) -> str | None:
"""Return the API connector ID for a given alias, or None."""
return self._alias_to_id.get(alias)
async def refresh_connector_async(self, alias: str) -> dict[str, type[BaseTool]]:
"""Re-fetch tools for a single connector by alias.
Updates the internal cache for that connector only. Returns
the new tool map (empty dict on failure).
"""
connector_id = self._alias_to_id.get(alias)
if connector_id is None:
return {}
try:
async with self._get_client() as client:
connector = await client.beta.connectors.get_async(
connector_id_or_name=connector_id
)
tools_map = await self._fetch_connector_tools(client, connector, alias)
except Exception:
logger.debug("Failed to refresh connector %s", alias)
tools_map = None
if self._cache is None:
self._cache = {}
if tools_map is None:
self._cache.pop(connector_id, None)
self._connector_connected[alias] = False
return {}
self._cache[connector_id] = tools_map
self._connector_connected[alias] = bool(tools_map)
return tools_map
async def get_auth_url(self, alias: str) -> str | None:
"""Return the OAuth authorization URL for a connector, or None.
Returns None when the connector does not support OAuth or the
alias is unknown.
"""
connector_id = self._alias_to_id.get(alias)
if connector_id is None:
return None
try:
async with self._get_client() as client:
result = await client.beta.connectors.get_auth_url_async(
connector_id_or_name=connector_id
)
return result.auth_url
except Exception:
logger.debug("Failed to get auth URL for connector %s", alias)
return None
def clear(self) -> None: def clear(self) -> None:
self._cache = None self._cache = None
self._connector_names = [] self._connector_names = []
self._connector_connected = {} self._connector_connected = {}
self._alias_to_id = {}

View file

@ -1,3 +1,8 @@
# What's new in v2.9.1
- **Default model**: Migrated to `mistral-medium-3.5`.
- **Connector OAuth**: Authenticate connectors via OAuth directly from the `/mcp` menu.
# What's new in v2.9.0 # What's new in v2.9.0
- **Scratchpad directory**: Model's autonomous workspace for temporary files, intermediate results, and drafts shared with subagents - **Scratchpad directory**: Model's autonomous workspace for temporary files, intermediate results, and drafts shared with subagents
- **`/copy` command**: New slash command to copy content directly from the conversation - **`/copy` command**: New slash command to copy content directly from the conversation