Co-authored-by: Quentin Torroba <quentin.torroba@mistral.ai>
Co-authored-by: Vincent Guilloux <vincent.guilloux@mistral.ai>
Co-authored-by: Thomas Kenbeek <thomas.kenbeek@mistral.ai>
Co-authored-by: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
Mathias Gesbert 2026-02-19 12:06:03 +01:00 committed by GitHub
parent ec7f3b25ea
commit a560a47ce8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
52 changed files with 1026 additions and 562 deletions

2
.vscode/launch.json vendored
View file

@ -1,5 +1,5 @@
{
"version": "2.2.0",
"version": "2.2.1",
"configurations": [
{
"name": "ACP Server",

View file

@ -5,6 +5,29 @@ 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/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.2.1] - 2026-02-18
### Added
- Multiple clipboard copy strategies: OSC52 first, then pyperclip fallback when system clipboard is available (e.g. local GUI, SSH without OSC52)
- Ctrl+Z to put Vibe in background
### Changed
- Improve performance around streaming and scrolling
- File watcher is now opt-out by default; opt-in via config
- Bump Textual version in dependencies
- Inline code styling: yellow bold with transparent background for better readability
### Fixed
- Banner: sync skills count after initial app mount (fixes wrong count in some cases)
- Collapsed tool results: strip newlines in truncation to remove extra blank line
- Context token widget: preserve stats listeners across `/clear` so token percentage updates correctly
- Vertex AI: cache credentials to avoid blocking the event loop on every LLM request
- Bash tool: remove `NO_COLOR` from subprocess env to fix snapshot tests and colored output
## [2.2.0] - 2026-02-17
### Added

View file

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

View file

@ -1,6 +1,6 @@
[project]
name = "mistral-vibe"
version = "2.2.0"
version = "2.2.1"
description = "Minimal CLI coding agent by Mistral"
readme = "README.md"
requires-python = ">=3.12"
@ -46,7 +46,7 @@ dependencies = [
"pyyaml>=6.0.0",
"requests>=2.20.0",
"rich>=14.0.0",
"textual>=1.0.0",
"textual>=7.4.0",
"textual-speedups>=0.2.1",
"tomli-w>=1.2.0",
"tree-sitter>=0.25.2",

View file

@ -28,7 +28,7 @@ class TestACPInitialize:
session_capabilities=SessionCapabilities(list=SessionListCapabilities()),
)
assert response.agent_info == Implementation(
name="@mistralai/mistral-vibe", title="Mistral Vibe", version="2.2.0"
name="@mistralai/mistral-vibe", title="Mistral Vibe", version="2.2.1"
)
assert response.auth_methods == []
@ -52,7 +52,7 @@ class TestACPInitialize:
session_capabilities=SessionCapabilities(list=SessionListCapabilities()),
)
assert response.agent_info == Implementation(
name="@mistralai/mistral-vibe", title="Mistral Vibe", version="2.2.0"
name="@mistralai/mistral-vibe", title="Mistral Vibe", version="2.2.1"
)
assert response.auth_methods is not None

View file

@ -16,7 +16,7 @@ from vibe.core.autocompletion.file_indexer import FileIndexer
@pytest.fixture
def file_indexer() -> Generator[FileIndexer]:
indexer = FileIndexer()
indexer = FileIndexer(should_enable_watcher=lambda: True)
yield indexer
indexer.shutdown()
@ -30,6 +30,20 @@ def _wait_for(condition: Callable[[], bool], timeout=3.0) -> bool:
return False
def _assert_index_state_stable(
file_indexer: FileIndexer,
expected_entries: set[str],
expected_incremental_updates: int,
duration: float = 1.0,
) -> None:
deadline = time.monotonic() + duration
while time.monotonic() < deadline:
current_entries = {entry.rel for entry in file_indexer.get_index(Path("."))}
assert current_entries == expected_entries
assert file_indexer.stats.incremental_updates == expected_incremental_updates
time.sleep(0.1)
def test_updates_index_on_file_creation(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch, file_indexer: FileIndexer
) -> None:
@ -143,7 +157,9 @@ def test_rebuilds_index_when_mass_change_threshold_is_exceeded(
# detected by the watcher
number_of_files = mass_change_threshold * 3
monkeypatch.chdir(tmp_path)
indexer = FileIndexer(mass_change_threshold=mass_change_threshold)
indexer = FileIndexer(
mass_change_threshold=mass_change_threshold, should_enable_watcher=lambda: True
)
try:
indexer.get_index(Path("."))
rebuilds_before = indexer.stats.rebuilds
@ -229,3 +245,101 @@ def test_shutdown_cleans_up_resources(
file_indexer.shutdown()
assert file_indexer.get_index(Path(".")) == []
def test_watcher_is_disabled_by_default(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.chdir(tmp_path)
file_indexer = FileIndexer()
try:
baseline_entries = {entry.rel for entry in file_indexer.get_index(Path("."))}
incremental_before = file_indexer.stats.incremental_updates
(tmp_path / "file.py").write_text("", encoding="utf-8")
_assert_index_state_stable(
file_indexer=file_indexer,
expected_entries=baseline_entries,
expected_incremental_updates=incremental_before,
)
finally:
file_indexer.shutdown()
def test_disabling_watcher_stops_runtime_updates(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.chdir(tmp_path)
watcher_enabled = True
file_indexer = FileIndexer(should_enable_watcher=lambda: watcher_enabled)
try:
tracked = tmp_path / "tracked.py"
tracked.write_text("", encoding="utf-8")
file_indexer.get_index(Path("."))
assert any(
entry.rel == "tracked.py" for entry in file_indexer.get_index(Path("."))
)
watcher_enabled = False
file_indexer.get_index(Path("."))
expected_entries = {entry.rel for entry in file_indexer.get_index(Path("."))}
incremental_before = file_indexer.stats.incremental_updates
tracked.unlink()
_assert_index_state_stable(
file_indexer=file_indexer,
expected_entries=expected_entries,
expected_incremental_updates=incremental_before,
)
finally:
file_indexer.shutdown()
def _current_entries(file_indexer: FileIndexer) -> set[str]:
return {entry.rel for entry in file_indexer.get_index(Path("."))}
def _assert_created_file_is_not_indexed(
file_indexer: FileIndexer, tmp_path: Path, filename: str
) -> None:
expected_entries = _current_entries(file_indexer)
expected_incremental_updates = file_indexer.stats.incremental_updates
(tmp_path / filename).write_text("", encoding="utf-8")
_assert_index_state_stable(
file_indexer=file_indexer,
expected_entries=expected_entries,
expected_incremental_updates=expected_incremental_updates,
)
def _assert_created_file_is_indexed(
file_indexer: FileIndexer, tmp_path: Path, filename: str
) -> None:
incremental_before = file_indexer.stats.incremental_updates
(tmp_path / filename).write_text("", encoding="utf-8")
assert _wait_for(lambda: filename in _current_entries(file_indexer))
assert file_indexer.stats.incremental_updates >= incremental_before + 1
def test_watcher_toggle_flow_off_on_off(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
monkeypatch.chdir(tmp_path)
watcher_enabled = False
file_indexer = FileIndexer(should_enable_watcher=lambda: watcher_enabled)
try:
file_indexer.get_index(Path("."))
_assert_created_file_is_not_indexed(file_indexer, tmp_path, "off_before.py")
watcher_enabled = True
file_indexer.get_index(Path("."))
_assert_created_file_is_indexed(file_indexer, tmp_path, "on_file.py")
watcher_enabled = False
file_indexer.get_index(Path("."))
_assert_created_file_is_not_indexed(file_indexer, tmp_path, "off_after.py")
finally:
file_indexer.shutdown()

View file

@ -13,8 +13,10 @@ the tests will be. Always prefer real API data over manually constructed example
from __future__ import annotations
import json
from unittest.mock import MagicMock, patch
import httpx
from mistralai.utils.retries import BackoffStrategy, RetryConfig
import pytest
import respx
@ -42,6 +44,16 @@ from vibe.core.utils import get_user_agent
class TestBackend:
@staticmethod
def _build_fast_retry_config() -> RetryConfig:
return RetryConfig(
strategy="backoff",
backoff=BackoffStrategy(
initial_interval=1, max_interval=1, exponent=1, max_elapsed_time=1
),
retry_connection_errors=False,
)
@pytest.mark.asyncio
@pytest.mark.parametrize(
"base_url,json_response,result_data",
@ -230,6 +242,8 @@ class TestBackend:
api_key_env_var="API_KEY",
)
backend = backend_class(provider=provider)
if isinstance(backend, MistralBackend):
backend._retry_config = self._build_fast_retry_config()
model = ModelConfig(
name="model_name", provider="provider_name", alias="model_alias"
)
@ -396,3 +410,28 @@ class TestBackend:
pass
assert mock_api.calls.last.request.headers["user-agent"] == user_agent
class TestMistralRetry:
@staticmethod
def _create_test_backend() -> MistralBackend:
provider = ProviderConfig(
name="test_provider",
api_base="https://api.mistral.ai/v1",
api_key_env_var="API_KEY",
)
return MistralBackend(provider=provider)
@pytest.mark.asyncio
async def test_client_creation_includes_timeout_and_retry_config(self):
backend = self._create_test_backend()
with patch("mistralai.Mistral") as mock_mistral_class:
mock_mistral_class.return_value = MagicMock()
backend._get_client()
mock_mistral_class.assert_called_once_with(
api_key=backend._api_key,
server_url=backend._server_url,
timeout_ms=720000,
retry_config=backend._retry_config,
)

View file

@ -1,13 +1,14 @@
from __future__ import annotations
import json
from unittest.mock import patch
from unittest.mock import MagicMock, PropertyMock, patch
import pytest
from vibe.core.config import ProviderConfig
from vibe.core.llm.backend.vertex import (
VertexAnthropicAdapter,
VertexCredentials,
build_vertex_base_url,
build_vertex_endpoint,
)
@ -16,7 +17,14 @@ from vibe.core.types import AvailableFunction, AvailableTool, LLMMessage, Role
@pytest.fixture
def adapter():
return VertexAnthropicAdapter()
adapter = VertexAnthropicAdapter()
with patch.object(
VertexCredentials,
"access_token",
new_callable=PropertyMock,
return_value="fake-token",
):
yield adapter
@pytest.fixture
@ -66,11 +74,7 @@ class TestBuildVertexEndpoint:
class TestPrepareRequest:
@patch(
"vibe.core.llm.backend.vertex.get_vertex_access_token",
return_value="fake-token",
)
def test_basic_request(self, mock_token, adapter, provider):
def test_basic_request(self, adapter, provider):
messages = [LLMMessage(role=Role.user, content="Hello")]
req = adapter.prepare_request(
model_name="claude-3-5-sonnet",
@ -94,11 +98,7 @@ class TestPrepareRequest:
assert "streamRawPredict" not in req.endpoint
assert req.base_url == "https://us-central1-aiplatform.googleapis.com"
@patch(
"vibe.core.llm.backend.vertex.get_vertex_access_token",
return_value="fake-token",
)
def test_streaming_request(self, mock_token, adapter, provider):
def test_streaming_request(self, adapter, provider):
messages = [LLMMessage(role=Role.user, content="Hello")]
req = adapter.prepare_request(
model_name="claude-3-5-sonnet",
@ -115,11 +115,7 @@ class TestPrepareRequest:
assert payload.get("stream") is True
assert "streamRawPredict" in req.endpoint
@patch(
"vibe.core.llm.backend.vertex.get_vertex_access_token",
return_value="fake-token",
)
def test_no_beta_features_for_vertex(self, mock_token, adapter, provider):
def test_no_beta_features_for_vertex(self, adapter, provider):
"""Vertex AI doesn't support the same beta features as direct Anthropic API."""
messages = [LLMMessage(role=Role.user, content="Hello")]
req = adapter.prepare_request(
@ -136,11 +132,7 @@ class TestPrepareRequest:
# Vertex AI doesn't support prompt-caching or other beta features
assert req.headers.get("anthropic-beta", "") == ""
@patch(
"vibe.core.llm.backend.vertex.get_vertex_access_token",
return_value="fake-token",
)
def test_with_extended_thinking(self, mock_token, adapter, provider):
def test_with_extended_thinking(self, adapter, provider):
messages = [LLMMessage(role=Role.user, content="Hello")]
req = adapter.prepare_request(
model_name="claude-3-5-sonnet",
@ -159,11 +151,7 @@ class TestPrepareRequest:
assert payload["max_tokens"] == 1024
assert payload["temperature"] == 1
@patch(
"vibe.core.llm.backend.vertex.get_vertex_access_token",
return_value="fake-token",
)
def test_with_tools(self, mock_token, adapter, provider):
def test_with_tools(self, adapter, provider):
messages = [LLMMessage(role=Role.user, content="Hello")]
tools = [
AvailableTool(
@ -227,11 +215,7 @@ class TestPrepareRequest:
provider=provider,
)
@patch(
"vibe.core.llm.backend.vertex.get_vertex_access_token",
return_value="fake-token",
)
def test_default_max_tokens(self, mock_token, adapter, provider):
def test_default_max_tokens(self, adapter, provider):
messages = [LLMMessage(role=Role.user, content="Hello")]
req = adapter.prepare_request(
model_name="claude-3-5-sonnet",
@ -589,3 +573,65 @@ class TestHelperMethods:
messages: list[dict] = []
adapter._add_cache_control_to_last_user_message(messages)
assert messages == []
class TestVertexCredentials:
def _make_creds(
self, *, valid: bool = True, token: str | None = "tok"
) -> MagicMock:
creds = MagicMock()
creds.valid = valid
creds.token = token
return creds
@patch("vibe.core.llm.backend.vertex.google.auth.default")
def test_initializes_credentials_on_first_access(self, mock_default: MagicMock):
creds = self._make_creds()
mock_default.return_value = (creds, "project")
vc = VertexCredentials()
token = vc.access_token
assert token == "tok"
mock_default.assert_called_once()
@patch("vibe.core.llm.backend.vertex.google.auth.default")
def test_caches_credentials_across_calls(self, mock_default: MagicMock):
creds = self._make_creds()
mock_default.return_value = (creds, "project")
vc = VertexCredentials()
_ = vc.access_token
_ = vc.access_token
_ = vc.access_token
mock_default.assert_called_once()
@patch("vibe.core.llm.backend.vertex.google.auth.default")
def test_refreshes_when_token_invalid(self, mock_default: MagicMock):
creds = self._make_creds(valid=False)
mock_default.return_value = (creds, "project")
vc = VertexCredentials()
_ = vc.access_token
creds.refresh.assert_called_once()
@patch("vibe.core.llm.backend.vertex.google.auth.default")
def test_skips_refresh_when_token_valid(self, mock_default: MagicMock):
creds = self._make_creds(valid=True)
mock_default.return_value = (creds, "project")
vc = VertexCredentials()
_ = vc.access_token
creds.refresh.assert_not_called()
@patch("vibe.core.llm.backend.vertex.google.auth.default")
def test_raises_when_token_is_none(self, mock_default: MagicMock):
creds = self._make_creds(valid=True, token=None)
mock_default.return_value = (creds, "project")
vc = VertexCredentials()
with pytest.raises(RuntimeError, match="did not produce a token"):
_ = vc.access_token

View file

@ -8,7 +8,15 @@ from unittest.mock import MagicMock, mock_open, patch
import pytest
from textual.app import App
from vibe.cli.clipboard import _copy_osc52, copy_selection_to_clipboard
from vibe.cli.clipboard import (
_copy_osc52,
_copy_pbcopy,
_copy_to_clipboard,
_copy_wl_copy,
_copy_xclip,
_read_clipboard,
copy_selection_to_clipboard,
)
class MockWidget:
@ -79,9 +87,9 @@ def test_copy_selection_to_clipboard_no_notification(
mock_app.notify.assert_not_called()
@patch("vibe.cli.clipboard._copy_osc52")
@patch("vibe.cli.clipboard._copy_to_clipboard")
def test_copy_selection_to_clipboard_success(
mock_copy_osc52: MagicMock, mock_app: MagicMock
mock_copy_to_clipboard: MagicMock, mock_app: MagicMock
) -> None:
widget = MockWidget(
text_selection=SimpleNamespace(), get_selection_result=("selected text", None)
@ -91,7 +99,7 @@ def test_copy_selection_to_clipboard_success(
result = copy_selection_to_clipboard(mock_app)
assert result == "selected text"
mock_copy_osc52.assert_called_once_with("selected text")
mock_copy_to_clipboard.assert_called_once_with("selected text")
mock_app.notify.assert_called_once_with(
'"selected text" copied to clipboard',
severity="information",
@ -100,21 +108,21 @@ def test_copy_selection_to_clipboard_success(
)
@patch("vibe.cli.clipboard._copy_osc52")
def test_copy_selection_to_clipboard_failure(
mock_copy_osc52: MagicMock, mock_app: MagicMock
@patch("vibe.cli.clipboard._copy_to_clipboard")
def test_copy_selection_to_clipboard_shows_failure_when_all_strategies_raise(
mock_copy_to_clipboard: MagicMock, mock_app: MagicMock
) -> None:
"""When _copy_to_clipboard raises (all strategies failed), user sees 'Failed to copy' toast."""
widget = MockWidget(
text_selection=SimpleNamespace(), get_selection_result=("selected text", None)
)
mock_app.query.return_value = [widget]
mock_copy_osc52.side_effect = Exception("OSC52 failed")
mock_copy_to_clipboard.side_effect = RuntimeError("All clipboard strategies failed")
result = copy_selection_to_clipboard(mock_app)
assert result is None
mock_copy_osc52.assert_called_once_with("selected text")
mock_copy_to_clipboard.assert_called_once_with("selected text")
mock_app.notify.assert_called_once_with(
"Failed to copy - clipboard not available", severity="warning", timeout=3
)
@ -131,11 +139,13 @@ def test_copy_selection_to_clipboard_multiple_widgets(mock_app: MagicMock) -> No
widget3 = MockWidget(text_selection=None)
mock_app.query.return_value = [widget1, widget2, widget3]
with patch("vibe.cli.clipboard._copy_osc52") as mock_copy_osc52:
with patch("vibe.cli.clipboard._copy_to_clipboard") as mock_copy_to_clipboard:
result = copy_selection_to_clipboard(mock_app)
assert result == "first selection\nsecond selection"
mock_copy_osc52.assert_called_once_with("first selection\nsecond selection")
mock_copy_to_clipboard.assert_called_once_with(
"first selection\nsecond selection"
)
mock_app.notify.assert_called_once_with(
'"first selection\u23cesecond selection" copied to clipboard',
severity="information",
@ -151,11 +161,11 @@ def test_copy_selection_to_clipboard_preview_shortening(mock_app: MagicMock) ->
)
mock_app.query.return_value = [widget]
with patch("vibe.cli.clipboard._copy_osc52") as mock_copy_osc52:
with patch("vibe.cli.clipboard._copy_to_clipboard") as mock_copy_to_clipboard:
result = copy_selection_to_clipboard(mock_app)
assert result == long_text
mock_copy_osc52.assert_called_once_with(long_text)
mock_copy_to_clipboard.assert_called_once_with(long_text)
notification_call = mock_app.notify.call_args
assert notification_call is not None
assert '"' in notification_call[0][0]
@ -163,6 +173,111 @@ def test_copy_selection_to_clipboard_preview_shortening(mock_app: MagicMock) ->
assert len(notification_call[0][0]) < len(long_text) + 30
def test_copy_to_clipboard_stops_after_verified_copy() -> None:
"""Stops iterating once _read_clipboard confirms the text landed."""
mock_first = MagicMock()
mock_second = MagicMock()
with (
patch("vibe.cli.clipboard._COPY_METHODS", [mock_first, mock_second]),
patch("vibe.cli.clipboard._read_clipboard", return_value="hello"),
):
_copy_to_clipboard("hello")
mock_first.assert_called_once_with("hello")
mock_second.assert_not_called()
def test_copy_to_clipboard_tries_all_when_verify_fails() -> None:
"""Tries all strategies when _read_clipboard never confirms."""
mock_first = MagicMock()
mock_second = MagicMock()
with (
patch("vibe.cli.clipboard._COPY_METHODS", [mock_first, mock_second]),
patch("vibe.cli.clipboard._read_clipboard", return_value=None),
):
_copy_to_clipboard("hello")
mock_first.assert_called_once_with("hello")
mock_second.assert_called_once_with("hello")
def test_copy_to_clipboard_raises_when_all_strategies_raise() -> None:
"""RuntimeError is raised when every strategy fails."""
mock_osc52 = MagicMock(side_effect=OSError("no tty"))
mock_pyperclip = MagicMock(side_effect=RuntimeError("pyperclip unavailable"))
with (
patch("vibe.cli.clipboard._COPY_METHODS", [mock_osc52, mock_pyperclip]),
pytest.raises(RuntimeError, match="All clipboard strategies failed"),
):
_copy_to_clipboard("anything")
def test_read_clipboard_returns_first_successful_reader() -> None:
mock_reader = MagicMock(return_value="hello")
mock_reader2 = MagicMock(side_effect=RuntimeError("no clipboard"))
with patch(
"vibe.cli.clipboard._READ_CLIPBOARD_METHODS", [mock_reader, mock_reader2]
):
assert _read_clipboard() == "hello"
mock_reader.assert_called_once()
mock_reader2.assert_not_called()
def test_read_clipboard_falls_through_on_failure() -> None:
failing = MagicMock(side_effect=RuntimeError("no clipboard"))
with patch("vibe.cli.clipboard._READ_CLIPBOARD_METHODS", [failing]):
assert _read_clipboard() is None
def test_read_clipboard_skips_failing_reader() -> None:
failing = MagicMock(side_effect=RuntimeError("broken"))
working = MagicMock(return_value="hello")
with patch("vibe.cli.clipboard._READ_CLIPBOARD_METHODS", [failing, working]):
assert _read_clipboard() == "hello"
working.assert_called_once()
@patch("subprocess.run")
def test_copy_pbcopy(mock_run: MagicMock) -> None:
_copy_pbcopy("hello")
mock_run.assert_called_once_with(["pbcopy"], input=b"hello", check=True)
@patch("subprocess.run")
def test_copy_xclip(mock_run: MagicMock) -> None:
_copy_xclip("hello")
mock_run.assert_called_once_with(
["xclip", "-selection", "clipboard"], input=b"hello", check=True
)
@patch("subprocess.run")
def test_copy_wl_copy(mock_run: MagicMock) -> None:
_copy_wl_copy("hello")
mock_run.assert_called_once_with(["wl-copy"], input=b"hello", check=True)
def test_copy_methods_includes_available_commands() -> None:
"""_COPY_METHODS is built at import time using _has_cmd; re-import with mocked shutil.which."""
import importlib
import vibe.cli.clipboard as mod
with patch(
"shutil.which",
side_effect=lambda cmd: "/usr/bin/xclip" if cmd == "xclip" else None,
):
importlib.reload(mod)
assert mod._copy_xclip in mod._COPY_METHODS
assert mod._copy_pbcopy not in mod._COPY_METHODS
assert mod._copy_wl_copy not in mod._COPY_METHODS
importlib.reload(mod)
@patch("builtins.open", new_callable=mock_open)
def test_copy_osc52_writes_correct_sequence(
mock_file: MagicMock, monkeypatch: pytest.MonkeyPatch

View file

@ -29,7 +29,7 @@ async def test_ui_clipboard_notification_does_not_crash_on_markup_text(
) -> None:
async with vibe_app.run_test(notifications=True) as pilot:
await vibe_app.mount(ClipboardSelectionWidget("[/]"))
with patch("vibe.cli.clipboard._copy_osc52"):
with patch("vibe.cli.clipboard._copy_to_clipboard"):
copy_selection_to_clipboard(vibe_app)
await pilot.pause(0.1)

View file

@ -193,5 +193,5 @@ async def test_ui_rebuilds_history_when_whats_new_is_shown(
assert message._content == "Hello from the previous session."
assert whats_new_message is not None
assert "after-history" in whats_new_message.classes
assert children == [message, assistant_message, whats_new_message]
assert whats_new_message.parent is not messages_area
assert children == [message, assistant_message]

View file

@ -111,17 +111,17 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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="215.2" textLength="134.2" clip-path="url(#terminal-line-8)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="215.2" textLength="146.4" clip-path="url(#terminal-line-8)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="215.2" textLength="122" clip-path="url(#terminal-line-8)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="215.2" textLength="183" clip-path="url(#terminal-line-8)">devstral-latest</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="0" y="239.6" textLength="134.2" clip-path="url(#terminal-line-9)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="239.6" textLength="414.8" clip-path="url(#terminal-line-9)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="264" textLength="134.2" clip-path="url(#terminal-line-10)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="264" textLength="61" clip-path="url(#terminal-line-10)">Type&#160;</text><text class="terminal-r3" x="231.8" y="264" textLength="61" clip-path="url(#terminal-line-10)">/help</text><text class="terminal-r1" x="292.8" y="264" textLength="256.2" clip-path="url(#terminal-line-10)">&#160;for&#160;more&#160;information</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)">

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Before After
Before After

View file

@ -141,28 +141,28 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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-r4" x="24.4" y="117.6" textLength="12.2" clip-path="url(#terminal-line-4)"></text><text class="terminal-r4" x="48.8" y="117.6" textLength="695.4" clip-path="url(#terminal-line-4)">What&#160;programming&#160;language&#160;are&#160;you&#160;currently&#160;working&#160;with?</text><text class="terminal-r1" x="1464" y="117.6" textLength="12.2" clip-path="url(#terminal-line-4)">
</text><text class="terminal-r4" x="24.4" y="142" textLength="12.2" clip-path="url(#terminal-line-5)"></text><text class="terminal-r1" x="48.8" y="142" textLength="48.8" clip-path="url(#terminal-line-5)">Rust</text><text class="terminal-r1" x="1464" y="142" textLength="12.2" clip-path="url(#terminal-line-5)">
</text><text class="terminal-r4" x="24.4" y="166.4" textLength="12.2" clip-path="url(#terminal-line-6)"></text><text class="terminal-r4" x="48.8" y="166.4" textLength="463.6" clip-path="url(#terminal-line-6)">What&#160;type&#160;of&#160;project&#160;are&#160;you&#160;building?</text><text class="terminal-r1" x="1464" y="166.4" textLength="12.2" clip-path="url(#terminal-line-6)">
</text><text class="terminal-r4" x="24.4" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)"></text><text class="terminal-r1" x="48.8" y="190.8" textLength="183" clip-path="url(#terminal-line-7)">Web&#160;Application</text><text class="terminal-r1" x="1464" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)">
</text><text class="terminal-r4" x="24.4" y="215.2" textLength="12.2" clip-path="url(#terminal-line-8)"></text><text class="terminal-r4" x="48.8" y="215.2" textLength="402.6" clip-path="url(#terminal-line-8)">What&#160;editor&#160;or&#160;IDE&#160;do&#160;you&#160;prefer?</text><text class="terminal-r1" x="1464" y="215.2" textLength="12.2" clip-path="url(#terminal-line-8)">
</text><text class="terminal-r4" x="24.4" y="239.6" textLength="12.2" clip-path="url(#terminal-line-9)"></text><text class="terminal-r1" x="48.8" y="239.6" textLength="183" clip-path="url(#terminal-line-9)">(Other)&#160;VS&#160;Code</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="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="0" y="312.8" textLength="134.2" clip-path="url(#terminal-line-12)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="312.8" textLength="146.4" clip-path="url(#terminal-line-12)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="312.8" textLength="122" clip-path="url(#terminal-line-12)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="312.8" textLength="183" clip-path="url(#terminal-line-12)">devstral-latest</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;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="337.2" textLength="414.8" clip-path="url(#terminal-line-13)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="361.6" textLength="61" clip-path="url(#terminal-line-14)">Type&#160;</text><text class="terminal-r3" x="231.8" y="361.6" textLength="61" clip-path="url(#terminal-line-14)">/help</text><text class="terminal-r1" x="292.8" y="361.6" textLength="256.2" clip-path="url(#terminal-line-14)">&#160;for&#160;more&#160;information</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="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-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="24.4" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"></text><text class="terminal-r4" x="48.8" y="410.4" textLength="695.4" clip-path="url(#terminal-line-16)">What&#160;programming&#160;language&#160;are&#160;you&#160;currently&#160;working&#160;with?</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r4" 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="48.8" clip-path="url(#terminal-line-17)">Rust</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="24.4" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"></text><text class="terminal-r4" x="48.8" y="459.2" textLength="463.6" clip-path="url(#terminal-line-18)">What&#160;type&#160;of&#160;project&#160;are&#160;you&#160;building?</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="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="183" clip-path="url(#terminal-line-19)">Web&#160;Application</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r4" x="24.4" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"></text><text class="terminal-r4" x="48.8" y="508" textLength="402.6" clip-path="url(#terminal-line-20)">What&#160;editor&#160;or&#160;IDE&#160;do&#160;you&#160;prefer?</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r4" 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="183" clip-path="url(#terminal-line-21)">(Other)&#160;VS&#160;Code</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="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r4" x="0" y="605.6" textLength="1464" clip-path="url(#terminal-line-24)">┌────────────────────────────────────────────────────────────────────────────────────────────────────────────&#160;default&#160;─┐</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before After
Before After

View file

@ -160,14 +160,14 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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-r4" x="0" y="142" textLength="12.2" clip-path="url(#terminal-line-5)"></text><text class="terminal-r2" x="24.4" y="142" textLength="305" clip-path="url(#terminal-line-5)">Hello&#160;there,&#160;who&#160;are&#160;you?</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="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="0" y="190.8" textLength="500.2" clip-path="url(#terminal-line-7)">I&#x27;m&#160;the&#160;Vibe&#160;agent&#160;and&#160;I&#x27;m&#160;ready&#160;to&#160;help.</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="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)">
@ -180,14 +180,14 @@
</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-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="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</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="183" clip-path="url(#terminal-line-20)">devstral-latest</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;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</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;0&#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="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="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-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="305" clip-path="url(#terminal-line-25)">Hello&#160;there,&#160;who&#160;are&#160;you?</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="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r1" x="0" y="678.8" textLength="500.2" clip-path="url(#terminal-line-27)">I&#x27;m&#160;the&#160;Vibe&#160;agent&#160;and&#160;I&#x27;m&#160;ready&#160;to&#160;help.</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="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</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="1464" clip-path="url(#terminal-line-30)">┌────────────────────────────────────────────────────────────────────────────────────────────────────────────&#160;default&#160;─┐</text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before After
Before After

View file

@ -40,7 +40,8 @@
.terminal-r6 { fill: #d2d2d2 }
.terminal-r7 { fill: #292929 }
.terminal-r8 { fill: #4b4e55 }
.terminal-r9 { fill: #9a9b99 }
.terminal-r9 { fill: #d0b344;font-weight: bold }
.terminal-r10 { fill: #9a9b99 }
</style>
<defs>
@ -162,44 +163,44 @@
</g>
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<rect fill="#4b4e55" x="12.2" y="245.5" width="158.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#9a9b99" x="48.8" y="294.3" width="61" height="24.65" shape-rendering="crispEdges"/>
<rect fill="#4b4e55" x="12.2" y="611.5" width="158.6" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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="0" y="142" textLength="451.4" clip-path="url(#terminal-line-5)">Here&#x27;s&#160;a&#160;very&#160;long&#160;print&#160;instruction:</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="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="0" y="190.8" textLength="36.6" clip-path="url(#terminal-line-7)">():</text><text class="terminal-r1" x="1464" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)">
</text><text class="terminal-r4" x="0" y="215.2" textLength="329.4" clip-path="url(#terminal-line-8)">ery&#160;long&#160;line&#160;(Lorem&#160;Ipsum)</text><text class="terminal-r1" x="1464" y="215.2" textLength="12.2" clip-path="url(#terminal-line-8)">
</text><text class="terminal-r5" x="0" y="239.6" textLength="1390.8" clip-path="url(#terminal-line-9)">m&#160;ipsum&#160;dolor&#160;sit&#160;amet,&#160;consectetur&#160;adipiscing&#160;elit.&#160;Sed&#160;do&#160;eiusmod&#160;tempor&#160;incididunt&#160;ut&#160;labore&#160;et&#160;dolore&#160;magna&#160;al</text><text class="terminal-r1" x="1464" y="239.6" textLength="12.2" clip-path="url(#terminal-line-9)">
</text><text class="terminal-r7" x="12.2" y="264" textLength="158.6" clip-path="url(#terminal-line-10)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-r8" x="170.8" y="264" textLength="12.2" clip-path="url(#terminal-line-10)"></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="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="0" y="312.8" textLength="48.8" clip-path="url(#terminal-line-12)">The&#160;</text><text class="terminal-r1" x="48.8" y="312.8" textLength="61" clip-path="url(#terminal-line-12)">print</text><text class="terminal-r1" x="109.8" y="312.8" textLength="1085.8" clip-path="url(#terminal-line-12)">&#160;statement&#160;includes&#160;a&#160;very&#160;long&#160;line&#160;of&#160;Lorem&#160;Ipsum&#160;text&#160;to&#160;demonstrate&#160;a&#160;lengthy&#160;output.</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="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="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</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="183" clip-path="url(#terminal-line-15)">devstral-latest</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;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="410.4" textLength="414.8" clip-path="url(#terminal-line-16)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#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="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="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="451.4" clip-path="url(#terminal-line-20)">Here&#x27;s&#160;a&#160;very&#160;long&#160;print&#160;instruction:</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="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="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="0" y="556.8" textLength="36.6" 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="329.4" clip-path="url(#terminal-line-23)">ery&#160;long&#160;line&#160;(Lorem&#160;Ipsum)</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="1390.8" clip-path="url(#terminal-line-24)">m&#160;ipsum&#160;dolor&#160;sit&#160;amet,&#160;consectetur&#160;adipiscing&#160;elit.&#160;Sed&#160;do&#160;eiusmod&#160;tempor&#160;incididunt&#160;ut&#160;labore&#160;et&#160;dolore&#160;magna&#160;al</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-r7" x="12.2" y="630" textLength="158.6" clip-path="url(#terminal-line-25)">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-r8" x="170.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-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="0" y="678.8" textLength="48.8" clip-path="url(#terminal-line-27)">The&#160;</text><text class="terminal-r9" x="48.8" y="678.8" textLength="61" clip-path="url(#terminal-line-27)">print</text><text class="terminal-r1" x="109.8" y="678.8" textLength="1085.8" clip-path="url(#terminal-line-27)">&#160;statement&#160;includes&#160;a&#160;very&#160;long&#160;line&#160;of&#160;Lorem&#160;Ipsum&#160;text&#160;to&#160;demonstrate&#160;a&#160;lengthy&#160;output.</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="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r9" x="0" y="752" textLength="1464" clip-path="url(#terminal-line-30)">┌────────────────────────────────────────────────────────────────────────────────────────────────────────────&#160;default&#160;─┐</text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">
</text><text class="terminal-r9" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r2" x="24.4" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)">&gt;</text><text class="terminal-r9" 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-r9" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r9" 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-r9" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r9" 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-r9" 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-r9" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r9" 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-r10" x="0" y="752" textLength="1464" clip-path="url(#terminal-line-30)">┌────────────────────────────────────────────────────────────────────────────────────────────────────────────&#160;default&#160;─┐</text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">
</text><text class="terminal-r10" x="0" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)"></text><text class="terminal-r2" x="24.4" y="776.4" textLength="12.2" clip-path="url(#terminal-line-31)">&gt;</text><text class="terminal-r10" 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-r10" x="0" y="800.8" textLength="12.2" clip-path="url(#terminal-line-32)"></text><text class="terminal-r10" 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-r10" x="0" y="825.2" textLength="12.2" clip-path="url(#terminal-line-33)"></text><text class="terminal-r10" 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-r10" 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-r10" x="0" y="874" textLength="158.6" clip-path="url(#terminal-line-35)">/test/workdir</text><text class="terminal-r10" 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>

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

@ -160,9 +160,9 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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)">
@ -184,9 +184,9 @@
</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="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-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r1" x="0" y="605.6" textLength="134.2" clip-path="url(#terminal-line-24)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="605.6" textLength="146.4" clip-path="url(#terminal-line-24)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="605.6" textLength="122" clip-path="url(#terminal-line-24)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="605.6" textLength="183" clip-path="url(#terminal-line-24)">devstral-latest</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="0" y="630" textLength="134.2" clip-path="url(#terminal-line-25)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="630" textLength="414.8" clip-path="url(#terminal-line-25)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r1" x="0" y="654.4" textLength="134.2" clip-path="url(#terminal-line-26)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="654.4" textLength="61" clip-path="url(#terminal-line-26)">Type&#160;</text><text class="terminal-r3" x="231.8" y="654.4" textLength="61" clip-path="url(#terminal-line-26)">/help</text><text class="terminal-r1" x="292.8" y="654.4" textLength="256.2" clip-path="url(#terminal-line-26)">&#160;for&#160;more&#160;information</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="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before After
Before After

View file

@ -160,9 +160,9 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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)">
@ -184,9 +184,9 @@
</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="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-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r1" x="0" y="605.6" textLength="134.2" clip-path="url(#terminal-line-24)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="605.6" textLength="146.4" clip-path="url(#terminal-line-24)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="605.6" textLength="122" clip-path="url(#terminal-line-24)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="605.6" textLength="183" clip-path="url(#terminal-line-24)">devstral-latest</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="0" y="630" textLength="134.2" clip-path="url(#terminal-line-25)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="630" textLength="414.8" clip-path="url(#terminal-line-25)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r1" x="0" y="654.4" textLength="134.2" clip-path="url(#terminal-line-26)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="654.4" textLength="61" clip-path="url(#terminal-line-26)">Type&#160;</text><text class="terminal-r3" x="231.8" y="654.4" textLength="61" clip-path="url(#terminal-line-26)">/help</text><text class="terminal-r1" x="292.8" y="654.4" textLength="256.2" clip-path="url(#terminal-line-26)">&#160;for&#160;more&#160;information</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="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before After
Before After

View file

@ -160,9 +160,9 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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)">
@ -184,9 +184,9 @@
</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="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-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r1" x="0" y="605.6" textLength="134.2" clip-path="url(#terminal-line-24)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="605.6" textLength="146.4" clip-path="url(#terminal-line-24)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="605.6" textLength="122" clip-path="url(#terminal-line-24)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="605.6" textLength="183" clip-path="url(#terminal-line-24)">devstral-latest</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="0" y="630" textLength="134.2" clip-path="url(#terminal-line-25)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="630" textLength="414.8" clip-path="url(#terminal-line-25)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r1" x="0" y="654.4" textLength="134.2" clip-path="url(#terminal-line-26)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="654.4" textLength="61" clip-path="url(#terminal-line-26)">Type&#160;</text><text class="terminal-r3" x="231.8" y="654.4" textLength="61" clip-path="url(#terminal-line-26)">/help</text><text class="terminal-r1" x="292.8" y="654.4" textLength="256.2" clip-path="url(#terminal-line-26)">&#160;for&#160;more&#160;information</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="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before After
Before After

View file

@ -159,9 +159,9 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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)">
@ -183,9 +183,9 @@
</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="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-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r1" x="0" y="605.6" textLength="134.2" clip-path="url(#terminal-line-24)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="605.6" textLength="146.4" clip-path="url(#terminal-line-24)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="605.6" textLength="122" clip-path="url(#terminal-line-24)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="605.6" textLength="183" clip-path="url(#terminal-line-24)">devstral-latest</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="0" y="630" textLength="134.2" clip-path="url(#terminal-line-25)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="630" textLength="414.8" clip-path="url(#terminal-line-25)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r1" x="0" y="654.4" textLength="134.2" clip-path="url(#terminal-line-26)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="654.4" textLength="61" clip-path="url(#terminal-line-26)">Type&#160;</text><text class="terminal-r3" x="231.8" y="654.4" textLength="61" clip-path="url(#terminal-line-26)">/help</text><text class="terminal-r1" x="292.8" y="654.4" textLength="256.2" clip-path="url(#terminal-line-26)">&#160;for&#160;more&#160;information</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="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before After
Before After

View file

@ -159,9 +159,9 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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)">
@ -183,9 +183,9 @@
</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="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-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r1" x="0" y="605.6" textLength="134.2" clip-path="url(#terminal-line-24)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="605.6" textLength="146.4" clip-path="url(#terminal-line-24)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="605.6" textLength="122" clip-path="url(#terminal-line-24)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="605.6" textLength="183" clip-path="url(#terminal-line-24)">devstral-latest</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="0" y="630" textLength="134.2" clip-path="url(#terminal-line-25)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="630" textLength="414.8" clip-path="url(#terminal-line-25)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)">
</text><text class="terminal-r1" x="0" y="654.4" textLength="134.2" clip-path="url(#terminal-line-26)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="654.4" textLength="61" clip-path="url(#terminal-line-26)">Type&#160;</text><text class="terminal-r3" x="231.8" y="654.4" textLength="61" clip-path="url(#terminal-line-26)">/help</text><text class="terminal-r1" x="292.8" y="654.4" textLength="256.2" clip-path="url(#terminal-line-26)">&#160;for&#160;more&#160;information</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="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before After
Before After

View file

@ -162,16 +162,16 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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-r4" x="0" y="142" textLength="12.2" clip-path="url(#terminal-line-5)"></text><text class="terminal-r2" x="24.4" y="142" textLength="207.4" clip-path="url(#terminal-line-5)">Give&#160;me&#160;an&#160;answer</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="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-r5" x="0" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)"></text><text class="terminal-r6" x="24.4" y="190.8" textLength="85.4" clip-path="url(#terminal-line-7)">Thought</text><text class="terminal-r6" x="122" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)"></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="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="0" y="239.6" textLength="707.6" clip-path="url(#terminal-line-9)">Here&#160;is&#160;my&#160;carefully&#160;considered&#160;answer.&#160;I&#160;hope&#160;this&#160;helps!</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="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)">
@ -180,16 +180,16 @@
</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-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-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="183" clip-path="url(#terminal-line-18)">devstral-latest</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="414.8" clip-path="url(#terminal-line-19)">1&#160;model&#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="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="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-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="207.4" clip-path="url(#terminal-line-23)">Give&#160;me&#160;an&#160;answer</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="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r6" x="24.4" y="630" textLength="85.4" clip-path="url(#terminal-line-25)">Thought</text><text class="terminal-r6" x="122" 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-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="0" y="678.8" textLength="707.6" clip-path="url(#terminal-line-27)">Here&#160;is&#160;my&#160;carefully&#160;considered&#160;answer.&#160;I&#160;hope&#160;this&#160;helps!</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="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r7" x="0" y="752" textLength="1464" clip-path="url(#terminal-line-30)">┌────────────────────────────────────────────────────────────────────────────────────────────────────────────&#160;default&#160;─┐</text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

@ -162,34 +162,34 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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-r4" x="0" y="142" textLength="12.2" clip-path="url(#terminal-line-5)"></text><text class="terminal-r2" x="24.4" y="142" textLength="219.6" clip-path="url(#terminal-line-5)">Explain&#160;this&#160;to&#160;me</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="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-r5" x="0" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)"></text><text class="terminal-r6" x="24.4" y="190.8" textLength="85.4" clip-path="url(#terminal-line-7)">Thought</text><text class="terminal-r6" x="122" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)"></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="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="0" y="239.6" textLength="439.2" clip-path="url(#terminal-line-9)">Here&#x27;s&#160;the&#160;first&#160;part&#160;of&#160;the&#160;answer.</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="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-r5" x="0" y="288.4" textLength="12.2" clip-path="url(#terminal-line-11)"></text><text class="terminal-r6" x="24.4" y="288.4" textLength="85.4" clip-path="url(#terminal-line-11)">Thought</text><text class="terminal-r6" x="122" 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="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="317.2" clip-path="url(#terminal-line-13)">And&#160;here&#x27;s&#160;the&#160;conclusion!</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="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="183" clip-path="url(#terminal-line-14)">devstral-latest</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="414.8" clip-path="url(#terminal-line-15)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#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="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="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-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="219.6" clip-path="url(#terminal-line-19)">Explain&#160;this&#160;to&#160;me</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="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"></text><text class="terminal-r6" x="24.4" y="532.4" textLength="85.4" clip-path="url(#terminal-line-21)">Thought</text><text class="terminal-r6" x="122" 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-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="0" y="581.2" textLength="439.2" clip-path="url(#terminal-line-23)">Here&#x27;s&#160;the&#160;first&#160;part&#160;of&#160;the&#160;answer.</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="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r6" x="24.4" y="630" textLength="85.4" clip-path="url(#terminal-line-25)">Thought</text><text class="terminal-r6" x="122" 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-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="0" y="678.8" textLength="317.2" clip-path="url(#terminal-line-27)">And&#160;here&#x27;s&#160;the&#160;conclusion!</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="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r7" x="0" y="752" textLength="1464" clip-path="url(#terminal-line-30)">┌────────────────────────────────────────────────────────────────────────────────────────────────────────────&#160;default&#160;─┐</text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

@ -162,16 +162,16 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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-r4" x="0" y="142" textLength="12.2" clip-path="url(#terminal-line-5)"></text><text class="terminal-r2" x="24.4" y="142" textLength="231.8" clip-path="url(#terminal-line-5)">What&#160;is&#160;the&#160;answer?</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="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-r5" x="0" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)"></text><text class="terminal-r6" x="24.4" y="190.8" textLength="85.4" clip-path="url(#terminal-line-7)">Thought</text><text class="terminal-r6" x="122" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)"></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="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="0" y="239.6" textLength="768.6" clip-path="url(#terminal-line-9)">The&#160;answer&#160;to&#160;your&#160;question&#160;is&#160;42.&#160;This&#160;is&#160;the&#160;ultimate&#160;answer.</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="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)">
@ -180,16 +180,16 @@
</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-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-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="183" clip-path="url(#terminal-line-18)">devstral-latest</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="414.8" clip-path="url(#terminal-line-19)">1&#160;model&#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="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="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-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="231.8" clip-path="url(#terminal-line-23)">What&#160;is&#160;the&#160;answer?</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="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r6" x="24.4" y="630" textLength="85.4" clip-path="url(#terminal-line-25)">Thought</text><text class="terminal-r6" x="122" 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-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="0" y="678.8" textLength="768.6" clip-path="url(#terminal-line-27)">The&#160;answer&#160;to&#160;your&#160;question&#160;is&#160;42.&#160;This&#160;is&#160;the&#160;ultimate&#160;answer.</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="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r7" x="0" y="752" textLength="1464" clip-path="url(#terminal-line-30)">┌────────────────────────────────────────────────────────────────────────────────────────────────────────────&#160;default&#160;─┐</text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

@ -162,34 +162,34 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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-r4" x="0" y="142" textLength="12.2" clip-path="url(#terminal-line-5)"></text><text class="terminal-r2" x="24.4" y="142" textLength="231.8" clip-path="url(#terminal-line-5)">What&#160;is&#160;the&#160;answer?</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="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-r5" x="0" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)"></text><text class="terminal-r6" x="24.4" y="190.8" textLength="85.4" clip-path="url(#terminal-line-7)">Thought</text><text class="terminal-r6" x="122" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)"></text><text class="terminal-r1" x="1464" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)">
</text><text class="terminal-r6" x="24.4" y="215.2" textLength="1390.8" clip-path="url(#terminal-line-8)">Let&#160;me&#160;think&#160;about&#160;this&#160;step&#160;by&#160;step...&#160;First,&#160;I&#160;need&#160;to&#160;understand&#160;the&#160;question.&#160;Then&#160;I&#160;can&#160;formulate&#160;a&#160;response.</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="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="0" y="264" textLength="768.6" clip-path="url(#terminal-line-10)">The&#160;answer&#160;to&#160;your&#160;question&#160;is&#160;42.&#160;This&#160;is&#160;the&#160;ultimate&#160;answer.</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="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="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-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="183" clip-path="url(#terminal-line-17)">devstral-latest</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;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-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="231.8" clip-path="url(#terminal-line-22)">What&#160;is&#160;the&#160;answer?</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="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="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r6" x="24.4" y="605.6" textLength="85.4" clip-path="url(#terminal-line-24)">Thought</text><text class="terminal-r6" x="122" 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-r6" x="24.4" y="630" textLength="1390.8" clip-path="url(#terminal-line-25)">Let&#160;me&#160;think&#160;about&#160;this&#160;step&#160;by&#160;step...&#160;First,&#160;I&#160;need&#160;to&#160;understand&#160;the&#160;question.&#160;Then&#160;I&#160;can&#160;formulate&#160;a&#160;response.</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="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r1" x="0" y="678.8" textLength="768.6" clip-path="url(#terminal-line-27)">The&#160;answer&#160;to&#160;your&#160;question&#160;is&#160;42.&#160;This&#160;is&#160;the&#160;ultimate&#160;answer.</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="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r7" x="0" y="752" textLength="1464" clip-path="url(#terminal-line-30)">┌────────────────────────────────────────────────────────────────────────────────────────────────────────────&#160;default&#160;─┐</text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

@ -163,13 +163,13 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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-r4" x="0" y="117.6" textLength="12.2" clip-path="url(#terminal-line-4)"></text><text class="terminal-r5" x="24.4" y="117.6" textLength="122" clip-path="url(#terminal-line-4)">What&#x27;s&#160;New</text><text class="terminal-r1" x="1464" y="117.6" textLength="12.2" clip-path="url(#terminal-line-4)">
</text><text class="terminal-r4" x="0" y="142" textLength="12.2" clip-path="url(#terminal-line-5)"></text><text class="terminal-r1" x="24.4" y="142" textLength="134.2" clip-path="url(#terminal-line-5)">&#160;Feature&#160;1</text><text class="terminal-r1" x="1464" y="142" textLength="12.2" clip-path="url(#terminal-line-5)">
</text><text class="terminal-r4" x="0" y="166.4" textLength="12.2" clip-path="url(#terminal-line-6)"></text><text class="terminal-r1" x="24.4" y="166.4" textLength="134.2" clip-path="url(#terminal-line-6)">&#160;Feature&#160;2</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="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)">
@ -183,13 +183,13 @@
</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-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="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</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="183" clip-path="url(#terminal-line-20)">devstral-latest</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;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</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;0&#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="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="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-r6" x="719.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-r6" x="719.8" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r7" x="744.2" y="654.4" textLength="195.2" clip-path="url(#terminal-line-26)">Update&#160;available</text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r4" x="0" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-r5" x="24.4" y="605.6" textLength="122" clip-path="url(#terminal-line-24)">What&#x27;s&#160;New</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="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r1" x="24.4" y="630" textLength="134.2" clip-path="url(#terminal-line-25)">&#160;Feature&#160;1</text><text class="terminal-r6" x="719.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-r4" x="0" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r1" x="24.4" y="654.4" textLength="134.2" clip-path="url(#terminal-line-26)">&#160;Feature&#160;2</text><text class="terminal-r6" x="719.8" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r7" x="744.2" y="654.4" textLength="195.2" clip-path="url(#terminal-line-26)">Update&#160;available</text><text class="terminal-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r6" x="719.8" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)"></text><text class="terminal-r1" x="744.2" y="678.8" textLength="207.4" clip-path="url(#terminal-line-27)">1.0.4&#160;=&gt;&#160;1000.2.0</text><text class="terminal-r1" x="1464" y="678.8" textLength="12.2" clip-path="url(#terminal-line-27)">
</text><text class="terminal-r6" x="719.8" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)"></text><text class="terminal-r1" x="744.2" y="703.2" textLength="634.4" clip-path="url(#terminal-line-28)">Please&#160;update&#160;mistral-vibe&#160;with&#160;your&#160;package&#160;manager</text><text class="terminal-r1" x="1464" y="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r6" x="719.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)">

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

@ -161,16 +161,16 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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-r4" x="0" y="142" textLength="12.2" clip-path="url(#terminal-line-5)"></text><text class="terminal-r2" x="24.4" y="142" textLength="231.8" clip-path="url(#terminal-line-5)">Hello,&#160;how&#160;are&#160;you?</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="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="0" y="190.8" textLength="695.4" clip-path="url(#terminal-line-7)">I&#x27;m&#160;doing&#160;well,&#160;thank&#160;you!&#160;Let&#160;me&#160;read&#160;that&#160;file&#160;for&#160;you.</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="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-r5" x="0" y="239.6" textLength="12.2" clip-path="url(#terminal-line-9)"></text><text class="terminal-r1" x="24.4" y="239.6" textLength="109.8" clip-path="url(#terminal-line-9)">read_file</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="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)">
@ -179,16 +179,16 @@
</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-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-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="183" clip-path="url(#terminal-line-18)">devstral-latest</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="414.8" clip-path="url(#terminal-line-19)">1&#160;model&#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="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="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-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="231.8" clip-path="url(#terminal-line-23)">Hello,&#160;how&#160;are&#160;you?</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-r1" x="0" y="630" textLength="695.4" clip-path="url(#terminal-line-25)">I&#x27;m&#160;doing&#160;well,&#160;thank&#160;you!&#160;Let&#160;me&#160;read&#160;that&#160;file&#160;for&#160;you.</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="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-r1" x="24.4" y="678.8" textLength="109.8" clip-path="url(#terminal-line-27)">read_file</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="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">
</text><text class="terminal-r6" x="0" y="752" textLength="1464" clip-path="url(#terminal-line-30)">┌────────────────────────────────────────────────────────────────────────────────────────────────────────────&#160;default&#160;─┐</text><text class="terminal-r1" x="1464" y="752" textLength="12.2" clip-path="url(#terminal-line-30)">

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

@ -161,14 +161,14 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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-r4" x="0" y="117.6" textLength="12.2" clip-path="url(#terminal-line-4)"></text><text class="terminal-r5" x="24.4" y="117.6" textLength="122" clip-path="url(#terminal-line-4)">What&#x27;s&#160;New</text><text class="terminal-r1" x="1464" y="117.6" textLength="12.2" clip-path="url(#terminal-line-4)">
</text><text class="terminal-r4" x="0" y="142" textLength="12.2" clip-path="url(#terminal-line-5)"></text><text class="terminal-r1" x="24.4" y="142" textLength="134.2" clip-path="url(#terminal-line-5)">&#160;Feature&#160;1</text><text class="terminal-r1" x="1464" y="142" textLength="12.2" clip-path="url(#terminal-line-5)">
</text><text class="terminal-r4" x="0" y="166.4" textLength="12.2" clip-path="url(#terminal-line-6)"></text><text class="terminal-r1" x="24.4" y="166.4" textLength="134.2" clip-path="url(#terminal-line-6)">&#160;Feature&#160;2</text><text class="terminal-r1" x="1464" y="166.4" textLength="12.2" clip-path="url(#terminal-line-6)">
</text><text class="terminal-r4" x="0" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)"></text><text class="terminal-r1" x="24.4" y="190.8" textLength="134.2" clip-path="url(#terminal-line-7)">&#160;Feature&#160;3</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="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)">
@ -180,14 +180,14 @@
</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="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-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</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="183" clip-path="url(#terminal-line-19)">devstral-latest</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;0&#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="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="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-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r4" x="0" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r5" x="24.4" y="581.2" textLength="122" clip-path="url(#terminal-line-23)">What&#x27;s&#160;New</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-r1" x="24.4" y="605.6" textLength="134.2" clip-path="url(#terminal-line-24)">&#160;Feature&#160;1</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="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r1" x="24.4" y="630" textLength="134.2" clip-path="url(#terminal-line-25)">&#160;Feature&#160;2</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="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r1" x="24.4" y="654.4" textLength="134.2" clip-path="url(#terminal-line-26)">&#160;Feature&#160;3</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="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

@ -162,33 +162,33 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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-r4" x="0" y="117.6" textLength="12.2" clip-path="url(#terminal-line-4)"></text><text class="terminal-r5" x="24.4" y="117.6" textLength="122" clip-path="url(#terminal-line-4)">What&#x27;s&#160;New</text><text class="terminal-r1" x="1464" y="117.6" textLength="12.2" clip-path="url(#terminal-line-4)">
</text><text class="terminal-r4" x="0" y="142" textLength="12.2" clip-path="url(#terminal-line-5)"></text><text class="terminal-r1" x="1464" y="142" textLength="12.2" clip-path="url(#terminal-line-5)">
</text><text class="terminal-r4" x="0" y="166.4" textLength="12.2" clip-path="url(#terminal-line-6)"></text><text class="terminal-r1" x="24.4" y="166.4" textLength="134.2" clip-path="url(#terminal-line-6)">&#160;Feature&#160;1</text><text class="terminal-r1" x="1464" y="166.4" textLength="12.2" clip-path="url(#terminal-line-6)">
</text><text class="terminal-r4" x="0" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)"></text><text class="terminal-r1" x="24.4" y="190.8" textLength="134.2" clip-path="url(#terminal-line-7)">&#160;Feature&#160;2</text><text class="terminal-r1" x="1464" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)">
</text><text class="terminal-r4" x="0" y="215.2" textLength="12.2" clip-path="url(#terminal-line-8)"></text><text class="terminal-r1" x="24.4" y="215.2" textLength="134.2" clip-path="url(#terminal-line-8)">&#160;Feature&#160;3</text><text class="terminal-r1" x="1464" y="215.2" textLength="12.2" clip-path="url(#terminal-line-8)">
</text><text class="terminal-r4" x="0" y="239.6" textLength="12.2" clip-path="url(#terminal-line-9)"></text><text class="terminal-r1" x="1464" y="239.6" textLength="12.2" clip-path="url(#terminal-line-9)">
</text><text class="terminal-r4" x="0" y="264" textLength="12.2" clip-path="url(#terminal-line-10)"></text><text class="terminal-r5" x="24.4" y="264" textLength="183" clip-path="url(#terminal-line-10)">Switch&#160;to&#160;your&#160;</text><text class="terminal-r6" x="207.4" y="264" textLength="231.8" clip-path="url(#terminal-line-10)">Le&#160;Chat&#160;Pro&#160;API&#160;key</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="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="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="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="183" clip-path="url(#terminal-line-16)">devstral-latest</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;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-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="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-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r4" x="0" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"></text><text class="terminal-r5" x="24.4" y="508" textLength="122" clip-path="url(#terminal-line-20)">What&#x27;s&#160;New</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-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-r1" x="24.4" y="556.8" textLength="134.2" clip-path="url(#terminal-line-22)">&#160;Feature&#160;1</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-r1" x="24.4" y="581.2" textLength="134.2" clip-path="url(#terminal-line-23)">&#160;Feature&#160;2</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-r1" x="24.4" y="605.6" textLength="134.2" clip-path="url(#terminal-line-24)">&#160;Feature&#160;3</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="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-r4" x="0" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r5" x="24.4" y="654.4" textLength="183" clip-path="url(#terminal-line-26)">Switch&#160;to&#160;your&#160;</text><text class="terminal-r6" x="207.4" y="654.4" textLength="231.8" clip-path="url(#terminal-line-26)">Le&#160;Chat&#160;Pro&#160;API&#160;key</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="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

@ -162,33 +162,33 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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-r4" x="0" y="117.6" textLength="12.2" clip-path="url(#terminal-line-4)"></text><text class="terminal-r5" x="24.4" y="117.6" textLength="122" clip-path="url(#terminal-line-4)">What&#x27;s&#160;New</text><text class="terminal-r1" x="1464" y="117.6" textLength="12.2" clip-path="url(#terminal-line-4)">
</text><text class="terminal-r4" x="0" y="142" textLength="12.2" clip-path="url(#terminal-line-5)"></text><text class="terminal-r1" x="1464" y="142" textLength="12.2" clip-path="url(#terminal-line-5)">
</text><text class="terminal-r4" x="0" y="166.4" textLength="12.2" clip-path="url(#terminal-line-6)"></text><text class="terminal-r1" x="24.4" y="166.4" textLength="134.2" clip-path="url(#terminal-line-6)">&#160;Feature&#160;1</text><text class="terminal-r1" x="1464" y="166.4" textLength="12.2" clip-path="url(#terminal-line-6)">
</text><text class="terminal-r4" x="0" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)"></text><text class="terminal-r1" x="24.4" y="190.8" textLength="134.2" clip-path="url(#terminal-line-7)">&#160;Feature&#160;2</text><text class="terminal-r1" x="1464" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)">
</text><text class="terminal-r4" x="0" y="215.2" textLength="12.2" clip-path="url(#terminal-line-8)"></text><text class="terminal-r1" x="24.4" y="215.2" textLength="134.2" clip-path="url(#terminal-line-8)">&#160;Feature&#160;3</text><text class="terminal-r1" x="1464" y="215.2" textLength="12.2" clip-path="url(#terminal-line-8)">
</text><text class="terminal-r4" x="0" y="239.6" textLength="12.2" clip-path="url(#terminal-line-9)"></text><text class="terminal-r1" x="1464" y="239.6" textLength="12.2" clip-path="url(#terminal-line-9)">
</text><text class="terminal-r4" x="0" y="264" textLength="12.2" clip-path="url(#terminal-line-10)"></text><text class="terminal-r5" x="24.4" y="264" textLength="292.8" clip-path="url(#terminal-line-10)">Unlock&#160;more&#160;with&#160;Vibe&#160;-&#160;</text><text class="terminal-r6" x="317.2" y="264" textLength="268.4" clip-path="url(#terminal-line-10)">Upgrade&#160;to&#160;Le&#160;Chat&#160;Pro</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="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="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="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="183" clip-path="url(#terminal-line-16)">devstral-latest</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;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-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="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-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r4" x="0" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"></text><text class="terminal-r5" x="24.4" y="508" textLength="122" clip-path="url(#terminal-line-20)">What&#x27;s&#160;New</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-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-r1" x="24.4" y="556.8" textLength="134.2" clip-path="url(#terminal-line-22)">&#160;Feature&#160;1</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-r1" x="24.4" y="581.2" textLength="134.2" clip-path="url(#terminal-line-23)">&#160;Feature&#160;2</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-r1" x="24.4" y="605.6" textLength="134.2" clip-path="url(#terminal-line-24)">&#160;Feature&#160;3</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="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-r4" x="0" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r5" x="24.4" y="654.4" textLength="292.8" clip-path="url(#terminal-line-26)">Unlock&#160;more&#160;with&#160;Vibe&#160;-&#160;</text><text class="terminal-r6" x="317.2" y="654.4" textLength="268.4" clip-path="url(#terminal-line-26)">Upgrade&#160;to&#160;Le&#160;Chat&#160;Pro</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="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

@ -161,14 +161,14 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix">
<text class="terminal-r1" x="0" y="20" textLength="134.2" clip-path="url(#terminal-line-0)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="20" textLength="146.4" clip-path="url(#terminal-line-0)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="20" textLength="122" clip-path="url(#terminal-line-0)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="20" textLength="183" clip-path="url(#terminal-line-0)">devstral-latest</text><text class="terminal-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-line-0)">
</text><text class="terminal-r1" x="0" y="44.4" textLength="134.2" clip-path="url(#terminal-line-1)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="44.4" textLength="414.8" clip-path="url(#terminal-line-1)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</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="0" y="68.8" textLength="134.2" clip-path="url(#terminal-line-2)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">Type&#160;</text><text class="terminal-r3" x="231.8" y="68.8" textLength="61" clip-path="url(#terminal-line-2)">/help</text><text class="terminal-r1" x="292.8" y="68.8" textLength="256.2" clip-path="url(#terminal-line-2)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-line-2)">
<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-r4" x="0" y="117.6" textLength="12.2" clip-path="url(#terminal-line-4)"></text><text class="terminal-r5" x="24.4" y="117.6" textLength="122" clip-path="url(#terminal-line-4)">What&#x27;s&#160;New</text><text class="terminal-r1" x="1464" y="117.6" textLength="12.2" clip-path="url(#terminal-line-4)">
</text><text class="terminal-r4" x="0" y="142" textLength="12.2" clip-path="url(#terminal-line-5)"></text><text class="terminal-r1" x="24.4" y="142" textLength="134.2" clip-path="url(#terminal-line-5)">&#160;Feature&#160;1</text><text class="terminal-r1" x="1464" y="142" textLength="12.2" clip-path="url(#terminal-line-5)">
</text><text class="terminal-r4" x="0" y="166.4" textLength="12.2" clip-path="url(#terminal-line-6)"></text><text class="terminal-r1" x="24.4" y="166.4" textLength="134.2" clip-path="url(#terminal-line-6)">&#160;Feature&#160;2</text><text class="terminal-r1" x="1464" y="166.4" textLength="12.2" clip-path="url(#terminal-line-6)">
</text><text class="terminal-r4" x="0" y="190.8" textLength="12.2" clip-path="url(#terminal-line-7)"></text><text class="terminal-r1" x="24.4" y="190.8" textLength="134.2" clip-path="url(#terminal-line-7)">&#160;Feature&#160;3</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="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)">
@ -180,14 +180,14 @@
</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="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-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</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="183" clip-path="url(#terminal-line-19)">devstral-latest</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;0&#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="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="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-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)">
</text><text class="terminal-r4" x="0" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"></text><text class="terminal-r5" x="24.4" y="581.2" textLength="122" clip-path="url(#terminal-line-23)">What&#x27;s&#160;New</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-r1" x="24.4" y="605.6" textLength="134.2" clip-path="url(#terminal-line-24)">&#160;Feature&#160;1</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="630" textLength="12.2" clip-path="url(#terminal-line-25)"></text><text class="terminal-r1" x="24.4" y="630" textLength="134.2" clip-path="url(#terminal-line-25)">&#160;Feature&#160;2</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="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"></text><text class="terminal-r1" x="24.4" y="654.4" textLength="134.2" clip-path="url(#terminal-line-26)">&#160;Feature&#160;3</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="703.2" textLength="12.2" clip-path="url(#terminal-line-28)">
</text><text class="terminal-r1" x="1464" y="727.6" textLength="12.2" clip-path="url(#terminal-line-29)">

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

@ -149,7 +149,7 @@ async def test_act_emits_user_and_assistant_msgs(observer_capture) -> None:
@pytest.mark.asyncio
async def test_act_streams_batched_chunks_in_order() -> None:
async def test_act_streams_chunks_in_order() -> None:
backend = FakeBackend([
mock_llm_chunk(content="Hello"),
mock_llm_chunk(content=" from"),
@ -166,10 +166,15 @@ async def test_act_streams_batched_chunks_in_order() -> None:
events = [event async for event in agent.act("Stream, please.")]
assistant_events = [e for e in events if isinstance(e, AssistantEvent)]
assert len(assistant_events) == 2
assert len(assistant_events) == 7
assert [event.content for event in assistant_events] == [
"Hello from Vibe! More",
" and end",
"Hello",
" from",
" Vibe",
"! ",
"More",
" and",
" end",
]
assert agent.messages[-1].role == Role.assistant
assert agent.messages[-1].content == "Hello from Vibe! More and end"
@ -248,12 +253,18 @@ async def test_act_handles_tool_call_chunk_with_content() -> None:
assert [type(event) for event in events] == [
UserMessageEvent,
AssistantEvent,
AssistantEvent,
AssistantEvent,
ToolCallEvent,
ToolResultEvent,
]
assert isinstance(events[0], UserMessageEvent)
assert isinstance(events[1], AssistantEvent)
assert events[1].content == "Preparing todo request complete"
assert isinstance(events[2], AssistantEvent)
assert isinstance(events[3], AssistantEvent)
assert events[1].content == "Preparing "
assert events[2].content == "todo request"
assert events[3].content == " complete"
assert any(
m.role == Role.assistant and m.content == "Preparing todo request complete"
for m in agent.messages
@ -360,6 +371,7 @@ async def test_act_handles_user_cancellation_during_streaming() -> None:
assert [type(event) for event in events] == [
UserMessageEvent,
AssistantEvent,
AssistantEvent,
ToolCallEvent,
ToolResultEvent,
]
@ -430,7 +442,7 @@ def _snapshot_events(events: list) -> list[tuple[str, str]]:
@pytest.mark.asyncio
async def test_reasoning_buffer_yields_before_content_on_transition() -> None:
async def test_reasoning_yields_before_content_on_transition() -> None:
backend = FakeBackend([
mock_llm_chunk(content="", reasoning_content="Let me think"),
mock_llm_chunk(content="", reasoning_content=" about this"),
@ -444,19 +456,21 @@ async def test_reasoning_buffer_yields_before_content_on_transition() -> None:
events = [event async for event in agent.act("What's the answer?")]
assert _snapshot_events(events) == [
("ReasoningEvent", "Let me think about this problem..."),
("ReasoningEvent", "Let me think"),
("ReasoningEvent", " about this"),
("ReasoningEvent", " problem..."),
("AssistantEvent", "The answer is 42."),
]
@pytest.mark.asyncio
async def test_reasoning_buffer_yields_before_content_with_batching() -> None:
async def test_reasoning_yields_per_chunk() -> None:
backend = FakeBackend([
mock_llm_chunk(content="", reasoning_content="Step 1"),
mock_llm_chunk(content="", reasoning_content=", Step 2"),
mock_llm_chunk(content="", reasoning_content=", Step 3"),
mock_llm_chunk(content="", reasoning_content=", Step 4"),
mock_llm_chunk(content="", reasoning_content=", Step 5"), # Triggers batch
mock_llm_chunk(content="", reasoning_content=", Step 5"),
mock_llm_chunk(content="", reasoning_content=", Step 6"),
mock_llm_chunk(content="", reasoning_content=", Final"),
mock_llm_chunk(content="Done thinking!"),
@ -468,15 +482,20 @@ async def test_reasoning_buffer_yields_before_content_with_batching() -> None:
events = [event async for event in agent.act("Think step by step")]
assert _snapshot_events(events) == [
("ReasoningEvent", "Step 1, Step 2, Step 3, Step 4, Step 5"),
("ReasoningEvent", ", Step 6, Final"),
("ReasoningEvent", "Step 1"),
("ReasoningEvent", ", Step 2"),
("ReasoningEvent", ", Step 3"),
("ReasoningEvent", ", Step 4"),
("ReasoningEvent", ", Step 5"),
("ReasoningEvent", ", Step 6"),
("ReasoningEvent", ", Final"),
("AssistantEvent", "Done thinking!"),
]
@pytest.mark.asyncio
async def test_content_buffer_yields_before_reasoning_on_transition() -> None:
"""When content is buffered and reasoning arrives, content yields first."""
async def test_content_yields_before_reasoning_on_transition() -> None:
"""When content chunks arrive and reasoning arrives, content yields first."""
backend = FakeBackend([
mock_llm_chunk(content="Starting the response"),
mock_llm_chunk(content=" here..."),
@ -491,8 +510,10 @@ async def test_content_buffer_yields_before_reasoning_on_transition() -> None:
events = [event async for event in agent.act("Give me an answer")]
assert _snapshot_events(events) == [
("AssistantEvent", "Starting the response here..."),
("ReasoningEvent", "Wait, let me reconsider this approach..."),
("AssistantEvent", "Starting the response"),
("AssistantEvent", " here..."),
("ReasoningEvent", "Wait, let me reconsider"),
("ReasoningEvent", " this approach..."),
("AssistantEvent", "Actually, the final answer."),
]
@ -540,7 +561,8 @@ async def test_only_reasoning_chunks_yields_reasoning_event() -> None:
events = [event async for event in agent.act("Silent thinking")]
assert _snapshot_events(events) == [
("ReasoningEvent", "Just thinking... nothing to say yet.")
("ReasoningEvent", "Just thinking..."),
("ReasoningEvent", " nothing to say yet."),
]
@ -566,7 +588,7 @@ async def test_final_buffers_flush_in_correct_order() -> None:
async def test_empty_content_chunks_do_not_trigger_false_yields() -> None:
backend = FakeBackend([
mock_llm_chunk(content="", reasoning_content="Reasoning here"),
mock_llm_chunk(content=""), # Empty content shouldn't flush reasoning
mock_llm_chunk(content=""), # Empty content shouldn't yield
mock_llm_chunk(content="", reasoning_content=" more reasoning"),
mock_llm_chunk(content="Actual content"),
])
@ -577,6 +599,7 @@ async def test_empty_content_chunks_do_not_trigger_false_yields() -> None:
events = [event async for event in agent.act("Empty content test")]
assert _snapshot_events(events) == [
("ReasoningEvent", "Reasoning here more reasoning"),
("ReasoningEvent", "Reasoning here"),
("ReasoningEvent", " more reasoning"),
("AssistantEvent", "Actual content"),
]

View file

@ -535,6 +535,27 @@ class TestAutoCompactIntegration:
class TestClearHistoryFullReset:
@pytest.mark.asyncio
async def test_clear_history_preserves_listeners(self) -> None:
backend = FakeBackend(mock_llm_chunk(content="Response"))
agent = build_test_agent_loop(config=make_config(), backend=backend)
listener_calls: list[int] = []
agent.stats.add_listener(
"context_tokens", lambda s: listener_calls.append(s.context_tokens)
)
async for _ in agent.act("Hello"):
pass
assert agent.stats.context_tokens > 0
listener_calls.clear()
await agent.clear_history()
assert agent.stats.context_tokens == 0
assert any(v == 0 for v in listener_calls)
@pytest.mark.asyncio
async def test_clear_history_fully_resets_stats(self) -> None:
backend = FakeBackend(mock_llm_chunk(content="Response"))

View file

@ -323,7 +323,7 @@ class TestAgentLoopStreamingReasoningEvents:
assert len(reasoning_events) == 0
assistant_events = [e for e in events if isinstance(e, AssistantEvent)]
assert len(assistant_events) == 1
assert len(assistant_events) == 2
assistant_msg = next(m for m in agent.messages if m.role == Role.assistant)
assert assistant_msg.reasoning_content is None

4
uv.lock generated
View file

@ -724,7 +724,7 @@ wheels = [
[[package]]
name = "mistral-vibe"
version = "2.2.0"
version = "2.2.1"
source = { editable = "." }
dependencies = [
{ name = "agent-client-protocol" },
@ -796,7 +796,7 @@ requires-dist = [
{ name = "pyyaml", specifier = ">=6.0.0" },
{ name = "requests", specifier = ">=2.20.0" },
{ name = "rich", specifier = ">=14.0.0" },
{ name = "textual", specifier = ">=1.0.0" },
{ name = "textual", specifier = ">=7.4.0" },
{ name = "textual-speedups", specifier = ">=0.2.1" },
{ name = "tomli-w", specifier = ">=1.2.0" },
{ name = "tree-sitter", specifier = ">=0.25.2" },

View file

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

View file

@ -1,8 +1,12 @@
from __future__ import annotations
import base64
from collections.abc import Callable
import os
import shutil
import subprocess
import pyperclip
from textual.app import App
_PREVIEW_MAX_LENGTH = 40
@ -19,6 +23,100 @@ def _copy_osc52(text: str) -> None:
tty.flush()
def _copy_pyperclip(text: str) -> None:
pyperclip.copy(text)
def _has_cmd(cmd: str) -> bool:
return shutil.which(cmd) is not None
def _copy_pbcopy(text: str) -> None:
subprocess.run(["pbcopy"], input=text.encode("utf-8"), check=True)
def _copy_xclip(text: str) -> None:
subprocess.run(
["xclip", "-selection", "clipboard"], input=text.encode("utf-8"), check=True
)
def _copy_wl_copy(text: str) -> None:
subprocess.run(["wl-copy"], input=text.encode("utf-8"), check=True)
_CMD_STRATEGIES: list[tuple[str, Callable[[str], None]]] = [
("pbcopy", _copy_pbcopy),
("xclip", _copy_xclip),
("wl-copy", _copy_wl_copy),
]
_COPY_METHODS: list[Callable[[str], None]] = [
_copy_osc52,
_copy_pyperclip,
*[fn for cmd, fn in _CMD_STRATEGIES if _has_cmd(cmd)],
]
def _paste_pyperclip() -> str:
return pyperclip.paste()
def _paste_pbpaste() -> str:
return subprocess.run(["pbpaste"], capture_output=True, check=True).stdout.decode(
"utf-8"
)
def _paste_xclip() -> str:
return subprocess.run(
["xclip", "-selection", "clipboard", "-o"], capture_output=True, check=True
).stdout.decode("utf-8")
def _paste_wl_paste() -> str:
return subprocess.run(["wl-paste"], capture_output=True, check=True).stdout.decode(
"utf-8"
)
_PASTE_CMD_STRATEGIES: list[tuple[str, Callable[[], str]]] = [
("pbpaste", _paste_pbpaste),
("xclip", _paste_xclip),
("wl-paste", _paste_wl_paste),
]
_READ_CLIPBOARD_METHODS: list[Callable[[], str]] = [
_paste_pyperclip,
*[fn for cmd, fn in _PASTE_CMD_STRATEGIES if _has_cmd(cmd)],
]
def _read_clipboard() -> str | None:
for reader in _READ_CLIPBOARD_METHODS:
try:
return reader()
except Exception:
pass
return None
def _copy_to_clipboard(text: str) -> None:
all_strategies_failed = True
for to_clipboard in _COPY_METHODS:
try:
to_clipboard(text)
except Exception:
pass
else:
all_strategies_failed = False
if _read_clipboard() == text:
return
if all_strategies_failed:
raise RuntimeError("All clipboard strategies failed")
def _shorten_preview(texts: list[str]) -> str:
dense_text = "".join(texts).replace("\n", "")
if len(dense_text) > _PREVIEW_MAX_LENGTH:
@ -26,7 +124,7 @@ def _shorten_preview(texts: list[str]) -> str:
return dense_text
def copy_selection_to_clipboard(app: App, show_toast: bool = True) -> str | None:
def _get_selected_texts(app: App) -> list[str]:
selected_texts = []
for widget in app.query("*"):
@ -47,13 +145,17 @@ def copy_selection_to_clipboard(app: App, show_toast: bool = True) -> str | None
if selected_text.strip():
selected_texts.append(selected_text)
return selected_texts
def copy_selection_to_clipboard(app: App, show_toast: bool = True) -> str | None:
selected_texts = _get_selected_texts(app)
if not selected_texts:
return None
combined_text = "\n".join(selected_texts)
try:
_copy_osc52(combined_text)
_copy_to_clipboard(combined_text)
if show_toast:
app.notify(
f'"{_shorten_preview(selected_texts)}" copied to clipboard',

View file

@ -2,16 +2,20 @@ from __future__ import annotations
import asyncio
from enum import StrEnum, auto
import os
from pathlib import Path
import signal
import subprocess
import time
from typing import Any, ClassVar, assert_never, cast
from weakref import WeakKeyDictionary
from pydantic import BaseModel
from textual.app import App, ComposeResult
from rich import print as rprint
from textual.app import WINDOWS, App, ComposeResult
from textual.binding import Binding, BindingType
from textual.containers import Horizontal, VerticalGroup, VerticalScroll
from textual.driver import Driver
from textual.events import AppBlur, AppFocus, MouseUp
from textual.widget import Widget
from textual.widgets import Static
@ -38,11 +42,9 @@ from vibe.cli.textual_ui.widgets.context_progress import ContextProgress, TokenS
from vibe.cli.textual_ui.widgets.load_more import HistoryLoadMoreRequested
from vibe.cli.textual_ui.widgets.loading import LoadingWidget, paused_timer
from vibe.cli.textual_ui.widgets.messages import (
AssistantMessage,
BashOutputMessage,
ErrorMessage,
InterruptMessage,
ReasoningMessage,
StreamingMessageBase,
UserCommandMessage,
UserMessage,
@ -54,7 +56,7 @@ from vibe.cli.textual_ui.widgets.path_display import PathDisplay
from vibe.cli.textual_ui.widgets.proxy_setup_app import ProxySetupApp
from vibe.cli.textual_ui.widgets.question_app import QuestionApp
from vibe.cli.textual_ui.widgets.teleport_message import TeleportMessage
from vibe.cli.textual_ui.widgets.tools import ToolCallMessage, ToolResultMessage
from vibe.cli.textual_ui.widgets.tools import ToolResultMessage
from vibe.cli.textual_ui.windowing import (
HISTORY_RESUME_TAIL_MESSAGES,
LOAD_MORE_BATCH_SIZE,
@ -180,6 +182,7 @@ class VibeApp(App): # noqa: PLR0904
BINDINGS: ClassVar[list[BindingType]] = [
Binding("ctrl+c", "clear_quit", "Quit", show=False),
Binding("ctrl+d", "force_quit", "Quit", show=False, priority=True),
Binding("ctrl+z", "suspend_with_message", "Suspend", show=False, priority=True),
Binding("escape", "interrupt", "Interrupt", show=False, priority=True),
Binding("ctrl+o", "toggle_tool", "Toggle Tool", show=False),
Binding("ctrl+y", "copy_selection", "Copy", show=False, priority=True),
@ -225,8 +228,6 @@ class VibeApp(App): # noqa: PLR0904
self.history_file = HISTORY_FILE.path
self._tools_collapsed = True
self._current_streaming_message: AssistantMessage | None = None
self._current_streaming_reasoning: ReasoningMessage | None = None
self._windowing = SessionWindowing(load_more_batch_size=LOAD_MORE_BATCH_SIZE)
self._load_more = HistoryLoadMoreManager()
self._tool_call_map: dict[str, str] | None = None
@ -239,9 +240,9 @@ class VibeApp(App): # noqa: PLR0904
self._plan_offer_gateway = plan_offer_gateway
self._initial_prompt = initial_prompt
self._teleport_on_start = teleport_on_start and self.config.nuage_enabled
self._auto_scroll = True
self._last_escape_time: float | None = None
self._banner: Banner | None = None
self._whats_new_message: WhatsNewMessage | None = None
self._cached_messages_area: Widget | None = None
self._cached_chat: ChatScroll | None = None
self._cached_loading_area: Widget | None = None
@ -267,6 +268,7 @@ class VibeApp(App): # noqa: PLR0904
safety=self.agent_loop.agent_profile.safety,
agent_name=self.agent_loop.agent_profile.display_name.lower(),
skill_entries_getter=self._get_skill_entries,
file_watcher_for_autocomplete_getter=self._is_file_watcher_enabled,
nuage_enabled=self.config.nuage_enabled,
)
@ -284,7 +286,6 @@ class VibeApp(App): # noqa: PLR0904
self.event_handler = EventHandler(
mount_callback=self._mount_and_scroll,
scroll_callback=self._scroll_to_bottom_deferred,
get_tools_collapsed=lambda: self._tools_collapsed,
)
@ -312,6 +313,8 @@ class VibeApp(App): # noqa: PLR0904
self._schedule_update_notification()
self.agent_loop.emit_new_session_telemetry("cli")
self.call_after_refresh(self._refresh_banner)
if self._initial_prompt or self._teleport_on_start:
self.call_after_refresh(self._process_initial_prompt)
@ -325,12 +328,19 @@ class VibeApp(App): # noqa: PLR0904
self._handle_user_message(self._initial_prompt), exclusive=False
)
def _is_file_watcher_enabled(self) -> bool:
return self.config.file_watcher_for_autocomplete
async def on_chat_input_container_submitted(
self, event: ChatInputContainer.Submitted
) -> None:
if self._banner:
self._banner.freeze_animation()
if self._whats_new_message:
await self._whats_new_message.remove()
self._whats_new_message = None
value = event.value.strip()
if not value:
return
@ -582,9 +592,7 @@ class VibeApp(App): # noqa: PLR0904
plan.tool_call_map,
start_index=plan.tail_start_index,
)
self.call_after_refresh(
lambda: self._align_chat_after_history_rebuild(plan.has_backfill)
)
self.call_after_refresh(self._scroll_chat_to_end)
self._tool_call_map = plan.tool_call_map
self._windowing.set_backfill(plan.backfill_messages)
await self._load_more.set_visible(
@ -703,7 +711,8 @@ class VibeApp(App): # noqa: PLR0904
if self._loading_widget:
await self._loading_widget.remove()
self._loading_widget = None
await self._finalize_current_streaming_message()
if self.event_handler:
await self.event_handler.finalize_streaming()
await self._refresh_windowing_from_history()
async def _teleport_command(self) -> None:
@ -814,6 +823,7 @@ class VibeApp(App): # noqa: PLR0904
if self.event_handler:
self.event_handler.stop_current_tool_call(success=False)
self.event_handler.stop_current_compact()
await self.event_handler.finalize_streaming()
self._agent_running = False
loading_area = self._cached_loading_area or self.query_one(
@ -822,7 +832,6 @@ class VibeApp(App): # noqa: PLR0904
await loading_area.remove_children()
self._loading_widget = None
await self._finalize_current_streaming_message()
await self._mount_and_scroll(InterruptMessage())
self._interrupt_requested = False
@ -881,7 +890,8 @@ class VibeApp(App): # noqa: PLR0904
self._tool_call_map = None
self._history_widget_indices = WeakKeyDictionary()
await self.agent_loop.clear_history()
await self._finalize_current_streaming_message()
if self.event_handler:
await self.event_handler.finalize_streaming()
messages_area = self._cached_messages_area or self.query_one("#messages")
await messages_area.remove_children()
@ -1019,7 +1029,7 @@ class VibeApp(App): # noqa: PLR0904
self.call_after_refresh(widget.focus)
if scroll:
self.call_after_refresh(self._scroll_to_bottom)
self.call_after_refresh(self._scroll_chat_to_end)
async def _switch_to_config_app(self) -> None:
if self._current_bottom_app == BottomApp.Config:
@ -1059,7 +1069,7 @@ class VibeApp(App): # noqa: PLR0904
self._chat_input_container.display = True
self._current_bottom_app = BottomApp.Input
self.call_after_refresh(self._chat_input_container.focus_input)
self.call_after_refresh(self._scroll_to_bottom)
self.call_after_refresh(self._scroll_chat_to_end)
def _focus_current_bottom_app(self) -> None:
try:
@ -1153,7 +1163,7 @@ class VibeApp(App): # noqa: PLR0904
self._handle_agent_running_escape()
self._last_escape_time = current_time
self._scroll_to_bottom()
self.call_after_refresh(self._scroll_chat_to_end)
self._focus_current_bottom_app()
async def on_history_load_more_requested(self, _: HistoryLoadMoreRequested) -> None:
@ -1211,6 +1221,10 @@ class VibeApp(App): # noqa: PLR0904
def _refresh_profile_widgets(self) -> None:
self._update_profile_widgets(self.agent_loop.agent_profile)
def _refresh_banner(self) -> None:
if self._banner:
self._banner.set_state(self.config, self.agent_loop.skill_manager)
def _update_profile_widgets(self, profile: AgentProfile) -> None:
if self._chat_input_container:
self._chat_input_container.set_safety(profile.safety)
@ -1245,7 +1259,6 @@ class VibeApp(App): # noqa: PLR0904
try:
chat = self._cached_chat or self.query_one("#chat", ChatScroll)
chat.scroll_relative(y=-5, animate=False)
self._auto_scroll = False
except Exception:
pass
@ -1253,8 +1266,6 @@ class VibeApp(App): # noqa: PLR0904
try:
chat = self._cached_chat or self.query_one("#chat", ChatScroll)
chat.scroll_relative(y=5, animate=False)
if self._is_scrolled_to_bottom(chat):
self._auto_scroll = True
except Exception:
pass
@ -1283,7 +1294,11 @@ class VibeApp(App): # noqa: PLR0904
whats_new_message = WhatsNewMessage(f"{content}\n\n{plan_offer}")
if self._history_widget_indices:
whats_new_message.add_class("after-history")
await self._mount_and_scroll(whats_new_message)
messages_area = self._cached_messages_area or self.query_one("#messages")
chat = self._cached_chat or self.query_one("#chat", ChatScroll)
await chat.mount(whats_new_message, after=messages_area)
self._whats_new_message = whats_new_message
chat.anchor()
await mark_version_as_seen(self._current_version, self._update_cache_repository)
async def _plan_offer_cta(self) -> str | None:
@ -1309,105 +1324,29 @@ class VibeApp(App): # noqa: PLR0904
)
return
async def _finalize_current_streaming_message(self) -> None:
if self._current_streaming_reasoning is not None:
self._current_streaming_reasoning.stop_spinning()
await self._current_streaming_reasoning.stop_stream()
self._current_streaming_reasoning = None
if self._current_streaming_message is None:
return
await self._current_streaming_message.stop_stream()
self._current_streaming_message = None
async def _handle_streaming_widget[T: StreamingMessageBase](
self,
widget: T,
current_stream: T | None,
other_stream: StreamingMessageBase | None,
messages_area: Widget,
) -> T | None:
if other_stream is not None:
await other_stream.stop_stream()
if current_stream is not None:
if widget._content:
await current_stream.append_content(widget._content)
return None
await messages_area.mount(widget)
await widget.write_initial_content()
return widget
def _scroll_chat_to_end(self) -> None:
chat = self._cached_chat or self.query_one("#chat", ChatScroll)
chat.scroll_end(animate=False)
async def _mount_and_scroll(self, widget: Widget) -> None:
messages_area = self._cached_messages_area or self.query_one("#messages")
chat = self._cached_chat or self.query_one("#chat", ChatScroll)
was_at_bottom = self._is_scrolled_to_bottom(chat)
result: Widget | None = None
if was_at_bottom:
self._auto_scroll = True
await messages_area.mount(widget)
if isinstance(widget, StreamingMessageBase):
await widget.write_initial_content()
if isinstance(widget, ReasoningMessage):
result = await self._handle_streaming_widget(
widget,
self._current_streaming_reasoning,
self._current_streaming_message,
messages_area,
)
if result is not None:
self._current_streaming_reasoning = result
self._current_streaming_message = None
elif isinstance(widget, AssistantMessage):
if self._current_streaming_reasoning is not None:
self._current_streaming_reasoning.stop_spinning()
result = await self._handle_streaming_widget(
widget,
self._current_streaming_message,
self._current_streaming_reasoning,
messages_area,
)
if result is not None:
self._current_streaming_message = result
self._current_streaming_reasoning = None
else:
await self._finalize_current_streaming_message()
await messages_area.mount(widget)
result = widget
is_tool_message = isinstance(widget, (ToolCallMessage, ToolResultMessage))
if not is_tool_message:
self.call_after_refresh(self._scroll_to_bottom)
if result is not None:
self.call_after_refresh(self._try_prune)
if was_at_bottom:
self.call_after_refresh(self._anchor_if_scrollable)
def _is_scrolled_to_bottom(self, scroll_view: VerticalScroll) -> bool:
try:
threshold = 3
return scroll_view.scroll_y >= (scroll_view.max_scroll_y - threshold)
except Exception:
return True
def _scroll_to_bottom(self) -> None:
try:
chat = self._cached_chat or self.query_one("#chat", ChatScroll)
chat.scroll_end(animate=False)
except Exception:
pass
def _scroll_to_bottom_deferred(self) -> None:
self.call_after_refresh(self._scroll_to_bottom)
self.call_after_refresh(self._try_prune)
chat.anchor()
async def _try_prune(self) -> None:
messages_area = self._cached_messages_area or self.query_one("#messages")
await prune_by_height(messages_area, PRUNE_LOW_MARK, PRUNE_HIGH_MARK)
pruned = await prune_by_height(messages_area, PRUNE_LOW_MARK, PRUNE_HIGH_MARK)
if self._load_more.widget and not self._load_more.widget.parent:
self._load_more.widget = None
if pruned:
chat = self._cached_chat or self.query_one("#chat", ChatScroll)
self.call_later(chat.anchor)
async def _refresh_windowing_from_history(self) -> None:
if self._load_more.widget is None:
@ -1424,29 +1363,6 @@ class VibeApp(App): # noqa: PLR0904
messages_area, visible=has_backfill, remaining=self._windowing.remaining
)
def _anchor_if_scrollable(self) -> None:
if not self._auto_scroll:
return
try:
chat = self._cached_chat or self.query_one("#chat", ChatScroll)
if chat.max_scroll_y == 0:
return
chat.anchor()
except Exception:
pass
def _align_chat_after_history_rebuild(self, has_backfill: bool) -> None:
try:
chat = self._cached_chat or self.query_one("#chat", ChatScroll)
if has_backfill and chat.max_scroll_y > 0:
chat.anchor(True)
chat.scroll_end(animate=False)
chat.anchor(False)
return
chat.scroll_end(animate=False)
except Exception:
pass
def _schedule_update_notification(self) -> None:
if self._update_notifier is None or not self.config.enable_update_checks:
return
@ -1516,6 +1432,20 @@ class VibeApp(App): # noqa: PLR0904
if self._chat_input_container and self._chat_input_container.input_widget:
self._chat_input_container.input_widget.set_app_focus(True)
def action_suspend_with_message(self) -> None:
if WINDOWS or self._driver is None or not self._driver.can_suspend:
return
with self.suspend():
rprint(
"Mistral Vibe has been suspended. Run [bold cyan]fg[/bold cyan] to bring Mistral Vibe back."
)
os.kill(os.getpid(), signal.SIGTSTP)
def _on_driver_signal_resume(self, event: Driver.SignalResume) -> None:
# Textual doesn't repaint after resuming from Ctrl+Z (SIGTSTP);
# force a full layout refresh so the UI isn't garbled.
self.refresh(layout=True)
def _print_session_resume_message(session_id: str | None) -> None:
if not session_id:

View file

@ -29,6 +29,7 @@ TextArea > .text-area--cursor {
width: 100%;
background: transparent;
padding: 0;
align-vertical: bottom;
}
#loading-area {
@ -147,8 +148,9 @@ Markdown {
color: ansi_default;
.code_inline {
color: ansi_default;
background: ansi_bright_black;
color: ansi_yellow;
background: transparent;
text-style: bold;
}
MarkdownFence {

View file

@ -27,16 +27,14 @@ if TYPE_CHECKING:
class EventHandler:
def __init__(
self,
mount_callback: Callable,
scroll_callback: Callable,
get_tools_collapsed: Callable[[], bool],
self, mount_callback: Callable, get_tools_collapsed: Callable[[], bool]
) -> None:
self.mount_callback = mount_callback
self.scroll_callback = scroll_callback
self.get_tools_collapsed = get_tools_collapsed
self.current_tool_call: ToolCallMessage | None = None
self.current_compact: CompactMessage | None = None
self.current_streaming_message: AssistantMessage | None = None
self.current_streaming_reasoning: ReasoningMessage | None = None
async def handle_event(
self,
@ -45,24 +43,29 @@ class EventHandler:
loading_widget: LoadingWidget | None = None,
) -> ToolCallMessage | None:
match event:
case ToolCallEvent():
return await self._handle_tool_call(event, loading_widget)
case ToolResultEvent():
sanitized_event = self._sanitize_event(event)
await self._handle_tool_result(sanitized_event)
case ToolStreamEvent():
await self._handle_tool_stream(event)
case ReasoningEvent():
await self._handle_reasoning_message(event)
case AssistantEvent():
await self._handle_assistant_message(event)
case ToolCallEvent():
await self.finalize_streaming()
return await self._handle_tool_call(event, loading_widget)
case ToolResultEvent():
await self.finalize_streaming()
sanitized_event = self._sanitize_event(event)
await self._handle_tool_result(sanitized_event)
case ToolStreamEvent():
await self._handle_tool_stream(event)
case CompactStartEvent():
await self.finalize_streaming()
await self._handle_compact_start()
case CompactEndEvent():
await self.finalize_streaming()
await self._handle_compact_end(event)
case UserMessageEvent():
pass
await self.finalize_streaming()
case _:
await self.finalize_streaming()
await self._handle_unknown_event(event)
return None
@ -113,13 +116,30 @@ class EventHandler:
self.current_tool_call.set_stream_message(event.message)
async def _handle_assistant_message(self, event: AssistantEvent) -> None:
await self.mount_callback(AssistantMessage(event.content))
if self.current_streaming_reasoning is not None:
self.current_streaming_reasoning.stop_spinning()
await self.current_streaming_reasoning.stop_stream()
self.current_streaming_reasoning = None
if self.current_streaming_message is None:
msg = AssistantMessage(event.content)
self.current_streaming_message = msg
await self.mount_callback(msg)
else:
await self.current_streaming_message.append_content(event.content)
async def _handle_reasoning_message(self, event: ReasoningEvent) -> None:
tools_collapsed = self.get_tools_collapsed()
await self.mount_callback(
ReasoningMessage(event.content, collapsed=tools_collapsed)
)
if self.current_streaming_message is not None:
await self.current_streaming_message.stop_stream()
self.current_streaming_message = None
if self.current_streaming_reasoning is None:
tools_collapsed = self.get_tools_collapsed()
msg = ReasoningMessage(event.content, collapsed=tools_collapsed)
self.current_streaming_reasoning = msg
await self.mount_callback(msg)
else:
await self.current_streaming_reasoning.append_content(event.content)
async def _handle_compact_start(self) -> None:
compact_msg = CompactMessage()
@ -136,6 +156,15 @@ class EventHandler:
async def _handle_unknown_event(self, event: BaseEvent) -> None:
await self.mount_callback(NoMarkupStatic(str(event), classes="unknown-event"))
async def finalize_streaming(self) -> None:
if self.current_streaming_reasoning is not None:
self.current_streaming_reasoning.stop_spinning()
await self.current_streaming_reasoning.stop_stream()
self.current_streaming_reasoning = None
if self.current_streaming_message is not None:
await self.current_streaming_message.stop_stream()
self.current_streaming_message = None
def stop_current_tool_call(self, success: bool = True) -> None:
if self.current_tool_call:
self.current_tool_call.stop_spinning(success=success)

View file

@ -42,6 +42,7 @@ class ChatInputContainer(Vertical):
safety: AgentSafety = AgentSafety.NEUTRAL,
agent_name: str = "",
skill_entries_getter: Callable[[], list[tuple[str, str]]] | None = None,
file_watcher_for_autocomplete_getter: Callable[[], bool] | None = None,
nuage_enabled: bool = False,
**kwargs: Any,
) -> None:
@ -51,11 +52,19 @@ class ChatInputContainer(Vertical):
self._safety = safety
self._agent_name = agent_name
self._skill_entries_getter = skill_entries_getter
self._file_watcher_for_autocomplete_getter = (
file_watcher_for_autocomplete_getter
)
self._nuage_enabled = nuage_enabled
self._completion_manager = MultiCompletionManager([
SlashCommandController(CommandCompleter(self._get_slash_entries), self),
PathCompletionController(PathCompleter(), self),
PathCompletionController(
PathCompleter(
watcher_enabled_getter=self._file_watcher_for_autocomplete_getter
),
self,
),
])
self._completion_popup: CompletionPopup | None = None
self._body: ChatInputBody | None = None

View file

@ -63,6 +63,12 @@ class ConfigApp(Container):
"type": "cycle",
"options": ["On", "Off"],
},
{
"key": "file_watcher_for_autocomplete",
"label": "Autocomplete watcher (may delay first autocompletion)",
"type": "cycle",
"options": ["On", "Off"],
},
]
self.title_widget: Static | None = None

View file

@ -25,9 +25,9 @@ from vibe.core.tools.builtins.write_file import WriteFileArgs, WriteFileResult
def _truncate_lines(content: str, max_lines: int) -> tuple[str, str | None]:
"""Truncate content to max_lines, returning (content, truncation_info)."""
lines = content.split("\n")
lines = content.strip("\n").split("\n")
if len(lines) <= max_lines:
return content, None
return "\n".join(lines), None
remaining = len(lines) - max_lines
return "\n".join(lines[:max_lines]), f"… ({remaining} more lines)"

View file

@ -5,7 +5,6 @@ from weakref import WeakKeyDictionary
from textual.widget import Widget
from vibe.cli.textual_ui.widgets.messages import WhatsNewMessage
from vibe.cli.textual_ui.windowing.history import (
build_tool_call_map,
split_history_tail,
@ -29,10 +28,7 @@ class HistoryResumePlan:
def should_resume_history(messages_children: list[Widget]) -> bool:
allowed_pre_existing_types = (WhatsNewMessage,)
return all(
isinstance(child, allowed_pre_existing_types) for child in messages_children
)
return len(messages_children) == 0
def create_resume_plan(

View file

@ -474,54 +474,21 @@ class AgentLoop:
async def _stream_assistant_events(
self,
) -> AsyncGenerator[AssistantEvent | ReasoningEvent]:
content_buffer = ""
reasoning_buffer = ""
chunks_with_content = 0
chunks_with_reasoning = 0
message_id: str | None = None
BATCH_SIZE = 5
async for chunk in self._chat_streaming():
if message_id is None:
message_id = chunk.message.message_id
if chunk.message.reasoning_content:
if content_buffer:
yield AssistantEvent(content=content_buffer, message_id=message_id)
content_buffer = ""
chunks_with_content = 0
reasoning_buffer += chunk.message.reasoning_content
chunks_with_reasoning += 1
if chunks_with_reasoning >= BATCH_SIZE:
yield ReasoningEvent(
content=reasoning_buffer, message_id=message_id
)
reasoning_buffer = ""
chunks_with_reasoning = 0
yield ReasoningEvent(
content=chunk.message.reasoning_content, message_id=message_id
)
if chunk.message.content:
if reasoning_buffer:
yield ReasoningEvent(
content=reasoning_buffer, message_id=message_id
)
reasoning_buffer = ""
chunks_with_reasoning = 0
content_buffer += chunk.message.content
chunks_with_content += 1
if chunks_with_content >= BATCH_SIZE:
yield AssistantEvent(content=content_buffer, message_id=message_id)
content_buffer = ""
chunks_with_content = 0
if reasoning_buffer:
yield ReasoningEvent(content=reasoning_buffer, message_id=message_id)
if content_buffer:
yield AssistantEvent(content=content_buffer, message_id=message_id)
yield AssistantEvent(
content=chunk.message.content, message_id=message_id
)
async def _get_assistant_event(self) -> AssistantEvent:
llm_result = await self._chat()
@ -933,7 +900,7 @@ class AgentLoop:
)
self.messages = self.messages[:1]
self.stats = AgentStats()
self.stats = AgentStats.create_fresh(self.stats)
self.stats.trigger_listeners()
try:

View file

@ -71,8 +71,9 @@ class PathCompleter(Completer):
self,
max_entries_to_process: int = DEFAULT_MAX_ENTRIES_TO_PROCESS,
target_matches: int = DEFAULT_TARGET_MATCHES,
watcher_enabled_getter: Callable[[], bool] | None = None,
) -> None:
self._indexer = FileIndexer()
self._indexer = FileIndexer(should_enable_watcher=watcher_enabled_getter)
self._max_entries_to_process = max_entries_to_process
self._target_matches = target_matches

View file

@ -1,7 +1,7 @@
from __future__ import annotations
import atexit
from collections.abc import Iterable
from collections.abc import Callable, Iterable
from concurrent.futures import ThreadPoolExecutor
from dataclasses import dataclass
from pathlib import Path
@ -23,7 +23,11 @@ class _RebuildTask:
class FileIndexer:
def __init__(self, mass_change_threshold: int = 200) -> None:
def __init__(
self,
mass_change_threshold: int = 200,
should_enable_watcher: Callable[[], bool] | None = None,
) -> None:
self._lock = RLock() # guards _store snapshot access and watcher callbacks.
self._stats = FileIndexStats()
self._ignore_rules = IgnoreRules()
@ -40,6 +44,7 @@ class FileIndexer:
) # coordinates updates to _active_rebuilds and _target_root.
self._target_root: Path | None = None
self._shutdown = False
self._should_enable_watcher = should_enable_watcher or (lambda: False)
atexit.register(self.shutdown)
@ -74,7 +79,10 @@ class FileIndexer:
self._start_background_rebuild(resolved_root)
self._wait_for_rebuild(resolved_root)
self._watcher.start(resolved_root)
if self._should_enable_watcher():
self._watcher.start(resolved_root)
else:
self._watcher.stop()
with self._lock: # ensure root reference is fresh before snapshotting
return self._store.snapshot()

View file

@ -311,6 +311,7 @@ class VibeConfig(BaseSettings):
vim_keybindings: bool = False
disable_welcome_banner_animation: bool = False
autocopy_to_clipboard: bool = True
file_watcher_for_autocomplete: bool = False
displayed_workdir: str = ""
auto_compact_threshold: int = 200_000
context_warnings: bool = False

View file

@ -9,6 +9,7 @@ from typing import TYPE_CHECKING, NamedTuple, cast
import httpx
import mistralai
from mistralai.utils.retries import BackoffStrategy, RetryConfig
from vibe.core.llm.exceptions import BackendErrorBuilder
from vibe.core.llm.message_utils import merge_consecutive_user_messages
@ -178,13 +179,22 @@ class MistralBackend:
)
self._server_url = match.group(1)
self._timeout = timeout
self._retry_config = self._build_retry_config()
def _build_retry_config(self) -> RetryConfig:
return RetryConfig(
strategy="backoff",
backoff=BackoffStrategy(
initial_interval=500,
max_interval=30000,
exponent=1.5,
max_elapsed_time=300000,
),
retry_connection_errors=True,
)
async def __aenter__(self) -> MistralBackend:
self._client = mistralai.Mistral(
api_key=self._api_key,
server_url=self._server_url,
timeout_ms=int(self._timeout * 1000),
)
self._client = self._create_mistral_client()
await self._client.__aenter__()
return self
@ -199,11 +209,17 @@ class MistralBackend:
exc_type=exc_type, exc_val=exc_val, exc_tb=exc_tb
)
def _create_mistral_client(self) -> mistralai.Mistral:
return mistralai.Mistral(
api_key=self._api_key,
server_url=self._server_url,
timeout_ms=int(self._timeout * 1000),
retry_config=self._retry_config,
)
def _get_client(self) -> mistralai.Mistral:
if self._client is None:
self._client = mistralai.Mistral(
api_key=self._api_key, server_url=self._server_url
)
self._client = self._create_mistral_client()
return self._client
async def complete(

View file

@ -1,9 +1,11 @@
from __future__ import annotations
import json
import threading
from typing import Any, ClassVar
import google.auth
import google.auth.credentials
from google.auth.transport.requests import Request
from vibe.core.config import ProviderConfig
@ -12,15 +14,6 @@ from vibe.core.llm.backend.base import PreparedRequest
from vibe.core.types import AvailableTool, LLMMessage, StrToolChoice
def get_vertex_access_token() -> str:
credentials, _ = google.auth.default(
scopes=["https://www.googleapis.com/auth/cloud-platform"]
)
credentials.refresh(Request())
return credentials.token
def build_vertex_base_url(region: str) -> str:
if region == "global":
return "https://aiplatform.googleapis.com"
@ -37,13 +30,39 @@ def build_vertex_endpoint(
)
class VertexCredentials:
def __init__(self) -> None:
self._credentials: google.auth.credentials.Credentials | None = None
self._lock = threading.Lock()
@property
def access_token(self) -> str:
with self._lock:
creds = self._credentials
if creds is None:
creds, _ = google.auth.default(
scopes=["https://www.googleapis.com/auth/cloud-platform"]
)
self._credentials = creds
if not creds.valid:
creds.refresh(Request())
if creds.token is None:
raise RuntimeError(
"Vertex AI credential refresh did not produce a token"
)
return creds.token
class VertexAnthropicAdapter(AnthropicAdapter):
"""Vertex AI adapter — inherits all streaming/parsing from AnthropicAdapter."""
endpoint: ClassVar[str] = ""
# Vertex AI doesn't support beta features
BETA_FEATURES: ClassVar[str] = ""
def __init__(self) -> None:
super().__init__()
self.credentials = VertexCredentials()
def prepare_request( # noqa: PLR0913
self,
*,
@ -70,7 +89,6 @@ class VertexAnthropicAdapter(AnthropicAdapter):
converted_tools = self._mapper.prepare_tools(tools)
converted_tool_choice = self._mapper.prepare_tool_choice(tool_choice)
# Build vertex-specific payload (no "model" key, uses anthropic_version)
payload: dict[str, Any] = {
"anthropic_version": "vertex-2023-10-16",
"messages": converted_messages,
@ -98,11 +116,9 @@ class VertexAnthropicAdapter(AnthropicAdapter):
self._add_cache_control_to_last_user_message(converted_messages)
access_token = get_vertex_access_token()
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {access_token}",
"Authorization": f"Bearer {self.credentials.access_token}",
"anthropic-beta": self.BETA_FEATURES,
}

View file

@ -72,13 +72,7 @@ def _get_shell_executable() -> str | None:
def _get_base_env() -> dict[str, str]:
base_env = {
**os.environ,
"CI": "true",
"NONINTERACTIVE": "1",
"NO_TTY": "1",
"NO_COLOR": "1",
}
base_env = {**os.environ, "CI": "true", "NONINTERACTIVE": "1", "NO_TTY": "1"}
if is_windows():
base_env["GIT_PAGER"] = "more"

View file

@ -61,6 +61,12 @@ class AgentStats(BaseModel):
) -> None:
self._listeners[attr_name] = listener
@staticmethod
def create_fresh(previous: AgentStats) -> AgentStats:
fresh = AgentStats()
fresh._listeners = previous._listeners.copy()
return fresh
@computed_field
@property
def session_total_llm_tokens(self) -> int:

View file

@ -1,5 +1,4 @@
# What's New in 2.2.0
# What's new
- **Agent Skills standard** — Vibe now discovers skills from `.agents/skills/` (agentskills.io) as well as `.vibe/skills/`.
Optional: usage and tool events are sent to our datalake to improve the product if you have a valid Mistral API key; set `disable_telemetry = true` in config to opt out.
- **Performance**: general improvements (streaming, scrolling).
- **Fix**: autocopying now behaves correctly in cases where it previously failed.