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": [ "configurations": [
{ {
"name": "ACP Server", "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/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.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 ## [2.2.0] - 2026-02-17
### Added ### Added

View file

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

View file

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

View file

@ -28,7 +28,7 @@ class TestACPInitialize:
session_capabilities=SessionCapabilities(list=SessionListCapabilities()), session_capabilities=SessionCapabilities(list=SessionListCapabilities()),
) )
assert response.agent_info == Implementation( 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 == [] assert response.auth_methods == []
@ -52,7 +52,7 @@ class TestACPInitialize:
session_capabilities=SessionCapabilities(list=SessionListCapabilities()), session_capabilities=SessionCapabilities(list=SessionListCapabilities()),
) )
assert response.agent_info == Implementation( 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 assert response.auth_methods is not None

View file

@ -16,7 +16,7 @@ from vibe.core.autocompletion.file_indexer import FileIndexer
@pytest.fixture @pytest.fixture
def file_indexer() -> Generator[FileIndexer]: def file_indexer() -> Generator[FileIndexer]:
indexer = FileIndexer() indexer = FileIndexer(should_enable_watcher=lambda: True)
yield indexer yield indexer
indexer.shutdown() indexer.shutdown()
@ -30,6 +30,20 @@ def _wait_for(condition: Callable[[], bool], timeout=3.0) -> bool:
return False 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( def test_updates_index_on_file_creation(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch, file_indexer: FileIndexer tmp_path: Path, monkeypatch: pytest.MonkeyPatch, file_indexer: FileIndexer
) -> None: ) -> None:
@ -143,7 +157,9 @@ def test_rebuilds_index_when_mass_change_threshold_is_exceeded(
# detected by the watcher # detected by the watcher
number_of_files = mass_change_threshold * 3 number_of_files = mass_change_threshold * 3
monkeypatch.chdir(tmp_path) 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: try:
indexer.get_index(Path(".")) indexer.get_index(Path("."))
rebuilds_before = indexer.stats.rebuilds rebuilds_before = indexer.stats.rebuilds
@ -229,3 +245,101 @@ def test_shutdown_cleans_up_resources(
file_indexer.shutdown() file_indexer.shutdown()
assert file_indexer.get_index(Path(".")) == [] 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 from __future__ import annotations
import json import json
from unittest.mock import MagicMock, patch
import httpx import httpx
from mistralai.utils.retries import BackoffStrategy, RetryConfig
import pytest import pytest
import respx import respx
@ -42,6 +44,16 @@ from vibe.core.utils import get_user_agent
class TestBackend: 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.asyncio
@pytest.mark.parametrize( @pytest.mark.parametrize(
"base_url,json_response,result_data", "base_url,json_response,result_data",
@ -230,6 +242,8 @@ class TestBackend:
api_key_env_var="API_KEY", api_key_env_var="API_KEY",
) )
backend = backend_class(provider=provider) backend = backend_class(provider=provider)
if isinstance(backend, MistralBackend):
backend._retry_config = self._build_fast_retry_config()
model = ModelConfig( model = ModelConfig(
name="model_name", provider="provider_name", alias="model_alias" name="model_name", provider="provider_name", alias="model_alias"
) )
@ -396,3 +410,28 @@ class TestBackend:
pass pass
assert mock_api.calls.last.request.headers["user-agent"] == user_agent 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 from __future__ import annotations
import json import json
from unittest.mock import patch from unittest.mock import MagicMock, PropertyMock, patch
import pytest import pytest
from vibe.core.config import ProviderConfig from vibe.core.config import ProviderConfig
from vibe.core.llm.backend.vertex import ( from vibe.core.llm.backend.vertex import (
VertexAnthropicAdapter, VertexAnthropicAdapter,
VertexCredentials,
build_vertex_base_url, build_vertex_base_url,
build_vertex_endpoint, build_vertex_endpoint,
) )
@ -16,7 +17,14 @@ from vibe.core.types import AvailableFunction, AvailableTool, LLMMessage, Role
@pytest.fixture @pytest.fixture
def adapter(): def adapter():
return VertexAnthropicAdapter() adapter = VertexAnthropicAdapter()
with patch.object(
VertexCredentials,
"access_token",
new_callable=PropertyMock,
return_value="fake-token",
):
yield adapter
@pytest.fixture @pytest.fixture
@ -66,11 +74,7 @@ class TestBuildVertexEndpoint:
class TestPrepareRequest: class TestPrepareRequest:
@patch( def test_basic_request(self, adapter, provider):
"vibe.core.llm.backend.vertex.get_vertex_access_token",
return_value="fake-token",
)
def test_basic_request(self, mock_token, adapter, provider):
messages = [LLMMessage(role=Role.user, content="Hello")] messages = [LLMMessage(role=Role.user, content="Hello")]
req = adapter.prepare_request( req = adapter.prepare_request(
model_name="claude-3-5-sonnet", model_name="claude-3-5-sonnet",
@ -94,11 +98,7 @@ class TestPrepareRequest:
assert "streamRawPredict" not in req.endpoint assert "streamRawPredict" not in req.endpoint
assert req.base_url == "https://us-central1-aiplatform.googleapis.com" assert req.base_url == "https://us-central1-aiplatform.googleapis.com"
@patch( def test_streaming_request(self, adapter, provider):
"vibe.core.llm.backend.vertex.get_vertex_access_token",
return_value="fake-token",
)
def test_streaming_request(self, mock_token, adapter, provider):
messages = [LLMMessage(role=Role.user, content="Hello")] messages = [LLMMessage(role=Role.user, content="Hello")]
req = adapter.prepare_request( req = adapter.prepare_request(
model_name="claude-3-5-sonnet", model_name="claude-3-5-sonnet",
@ -115,11 +115,7 @@ class TestPrepareRequest:
assert payload.get("stream") is True assert payload.get("stream") is True
assert "streamRawPredict" in req.endpoint assert "streamRawPredict" in req.endpoint
@patch( def test_no_beta_features_for_vertex(self, adapter, provider):
"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):
"""Vertex AI doesn't support the same beta features as direct Anthropic API.""" """Vertex AI doesn't support the same beta features as direct Anthropic API."""
messages = [LLMMessage(role=Role.user, content="Hello")] messages = [LLMMessage(role=Role.user, content="Hello")]
req = adapter.prepare_request( req = adapter.prepare_request(
@ -136,11 +132,7 @@ class TestPrepareRequest:
# Vertex AI doesn't support prompt-caching or other beta features # Vertex AI doesn't support prompt-caching or other beta features
assert req.headers.get("anthropic-beta", "") == "" assert req.headers.get("anthropic-beta", "") == ""
@patch( def test_with_extended_thinking(self, adapter, provider):
"vibe.core.llm.backend.vertex.get_vertex_access_token",
return_value="fake-token",
)
def test_with_extended_thinking(self, mock_token, adapter, provider):
messages = [LLMMessage(role=Role.user, content="Hello")] messages = [LLMMessage(role=Role.user, content="Hello")]
req = adapter.prepare_request( req = adapter.prepare_request(
model_name="claude-3-5-sonnet", model_name="claude-3-5-sonnet",
@ -159,11 +151,7 @@ class TestPrepareRequest:
assert payload["max_tokens"] == 1024 assert payload["max_tokens"] == 1024
assert payload["temperature"] == 1 assert payload["temperature"] == 1
@patch( def test_with_tools(self, adapter, provider):
"vibe.core.llm.backend.vertex.get_vertex_access_token",
return_value="fake-token",
)
def test_with_tools(self, mock_token, adapter, provider):
messages = [LLMMessage(role=Role.user, content="Hello")] messages = [LLMMessage(role=Role.user, content="Hello")]
tools = [ tools = [
AvailableTool( AvailableTool(
@ -227,11 +215,7 @@ class TestPrepareRequest:
provider=provider, provider=provider,
) )
@patch( def test_default_max_tokens(self, adapter, provider):
"vibe.core.llm.backend.vertex.get_vertex_access_token",
return_value="fake-token",
)
def test_default_max_tokens(self, mock_token, adapter, provider):
messages = [LLMMessage(role=Role.user, content="Hello")] messages = [LLMMessage(role=Role.user, content="Hello")]
req = adapter.prepare_request( req = adapter.prepare_request(
model_name="claude-3-5-sonnet", model_name="claude-3-5-sonnet",
@ -589,3 +573,65 @@ class TestHelperMethods:
messages: list[dict] = [] messages: list[dict] = []
adapter._add_cache_control_to_last_user_message(messages) adapter._add_cache_control_to_last_user_message(messages)
assert 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 import pytest
from textual.app import App 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: class MockWidget:
@ -79,9 +87,9 @@ def test_copy_selection_to_clipboard_no_notification(
mock_app.notify.assert_not_called() 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( def test_copy_selection_to_clipboard_success(
mock_copy_osc52: MagicMock, mock_app: MagicMock mock_copy_to_clipboard: MagicMock, mock_app: MagicMock
) -> None: ) -> None:
widget = MockWidget( widget = MockWidget(
text_selection=SimpleNamespace(), get_selection_result=("selected text", None) 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) result = copy_selection_to_clipboard(mock_app)
assert result == "selected text" 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( mock_app.notify.assert_called_once_with(
'"selected text" copied to clipboard', '"selected text" copied to clipboard',
severity="information", severity="information",
@ -100,21 +108,21 @@ def test_copy_selection_to_clipboard_success(
) )
@patch("vibe.cli.clipboard._copy_osc52") @patch("vibe.cli.clipboard._copy_to_clipboard")
def test_copy_selection_to_clipboard_failure( def test_copy_selection_to_clipboard_shows_failure_when_all_strategies_raise(
mock_copy_osc52: MagicMock, mock_app: MagicMock mock_copy_to_clipboard: MagicMock, mock_app: MagicMock
) -> None: ) -> None:
"""When _copy_to_clipboard raises (all strategies failed), user sees 'Failed to copy' toast."""
widget = MockWidget( widget = MockWidget(
text_selection=SimpleNamespace(), get_selection_result=("selected text", None) text_selection=SimpleNamespace(), get_selection_result=("selected text", None)
) )
mock_app.query.return_value = [widget] mock_app.query.return_value = [widget]
mock_copy_to_clipboard.side_effect = RuntimeError("All clipboard strategies failed")
mock_copy_osc52.side_effect = Exception("OSC52 failed")
result = copy_selection_to_clipboard(mock_app) result = copy_selection_to_clipboard(mock_app)
assert result is None 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( mock_app.notify.assert_called_once_with(
"Failed to copy - clipboard not available", severity="warning", timeout=3 "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) widget3 = MockWidget(text_selection=None)
mock_app.query.return_value = [widget1, widget2, widget3] 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) result = copy_selection_to_clipboard(mock_app)
assert result == "first selection\nsecond selection" 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( mock_app.notify.assert_called_once_with(
'"first selection\u23cesecond selection" copied to clipboard', '"first selection\u23cesecond selection" copied to clipboard',
severity="information", severity="information",
@ -151,11 +161,11 @@ def test_copy_selection_to_clipboard_preview_shortening(mock_app: MagicMock) ->
) )
mock_app.query.return_value = [widget] 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) result = copy_selection_to_clipboard(mock_app)
assert result == long_text 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 notification_call = mock_app.notify.call_args
assert notification_call is not None assert notification_call is not None
assert '"' in notification_call[0][0] 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 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) @patch("builtins.open", new_callable=mock_open)
def test_copy_osc52_writes_correct_sequence( def test_copy_osc52_writes_correct_sequence(
mock_file: MagicMock, monkeypatch: pytest.MonkeyPatch 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: ) -> None:
async with vibe_app.run_test(notifications=True) as pilot: async with vibe_app.run_test(notifications=True) as pilot:
await vibe_app.mount(ClipboardSelectionWidget("[/]")) 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) copy_selection_to_clipboard(vibe_app)
await pilot.pause(0.1) 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 message._content == "Hello from the previous session."
assert whats_new_message is not None assert whats_new_message is not None
assert "after-history" in whats_new_message.classes assert whats_new_message.parent is not messages_area
assert children == [message, assistant_message, whats_new_message] assert children == [message, assistant_message]

View file

@ -111,17 +111,17 @@
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)"> <g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix"> <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 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="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><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="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="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="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="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="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="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="1464" y="239.6" textLength="12.2" clip-path="url(#terminal-line-9)"> </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="1464" y="264" textLength="12.2" clip-path="url(#terminal-line-10)"> </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="288.4" textLength="12.2" clip-path="url(#terminal-line-11)">
</text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)"> </text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)">
</text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)"> </text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)">

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 transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix"> <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 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="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><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="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-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-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-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-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-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="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="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="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="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="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)"> </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="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)"> </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="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-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-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </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-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </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-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </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-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </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-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </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="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r4" x="0" y="605.6" textLength="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)"> </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 transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix"> <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 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="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><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="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="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="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="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="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="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="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r1" x="0" y="508" textLength="134.2" clip-path="url(#terminal-line-20)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="508" textLength="146.4" clip-path="url(#terminal-line-20)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="508" textLength="122" clip-path="url(#terminal-line-20)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="508" textLength="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="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r1" x="0" y="532.4" textLength="134.2" clip-path="url(#terminal-line-21)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="532.4" textLength="414.8" clip-path="url(#terminal-line-21)">1&#160;model&#160;·&#160;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="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="0" y="556.8" textLength="134.2" clip-path="url(#terminal-line-22)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="556.8" textLength="61" clip-path="url(#terminal-line-22)">Type&#160;</text><text class="terminal-r3" x="231.8" y="556.8" textLength="61" clip-path="url(#terminal-line-22)">/help</text><text class="terminal-r1" x="292.8" y="556.8" textLength="256.2" clip-path="url(#terminal-line-22)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)">
</text><text class="terminal-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="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="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-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)"> </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-r6 { fill: #d2d2d2 }
.terminal-r7 { fill: #292929 } .terminal-r7 { fill: #292929 }
.terminal-r8 { fill: #4b4e55 } .terminal-r8 { fill: #4b4e55 }
.terminal-r9 { fill: #9a9b99 } .terminal-r9 { fill: #d0b344;font-weight: bold }
.terminal-r10 { fill: #9a9b99 }
</style> </style>
<defs> <defs>
@ -162,44 +163,44 @@
</g> </g>
<g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)"> <g transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<rect fill="#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"> <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 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="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><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="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="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="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-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-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-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="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="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="337.2" textLength="12.2" clip-path="url(#terminal-line-13)">
</text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)"> </text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)">
</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)"> </text><text class="terminal-r1" x="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="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="0" y="410.4" textLength="134.2" clip-path="url(#terminal-line-16)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="410.4" textLength="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="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="0" y="434.8" textLength="134.2" clip-path="url(#terminal-line-17)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="434.8" textLength="61" clip-path="url(#terminal-line-17)">Type&#160;</text><text class="terminal-r3" x="231.8" y="434.8" textLength="61" clip-path="url(#terminal-line-17)">/help</text><text class="terminal-r1" x="292.8" y="434.8" textLength="256.2" clip-path="url(#terminal-line-17)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="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="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="0" y="556.8" textLength="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-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="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-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r5" x="0" y="605.6" textLength="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-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </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="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="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-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-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-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-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-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-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-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-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-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-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-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="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>
</g> </g>
</svg> </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 transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix"> <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 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="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><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="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="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="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="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </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="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </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="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </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="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="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-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 transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix"> <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 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="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><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="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="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="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="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </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="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </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="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </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="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="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-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 transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix"> <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 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="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><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="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="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="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="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </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="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </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="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </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="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="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-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 transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix"> <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 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="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><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="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="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="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="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </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="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </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="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </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="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="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-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 transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix"> <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 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="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><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="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="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="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="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </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="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </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="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </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="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="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-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 transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix"> <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 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="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><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="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="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-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="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="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="288.4" textLength="12.2" clip-path="url(#terminal-line-11)">
</text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)"> </text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)">
@ -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="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="459.2" textLength="146.4" clip-path="url(#terminal-line-18)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="459.2" textLength="122" clip-path="url(#terminal-line-18)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="459.2" textLength="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="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="483.6" textLength="414.8" clip-path="url(#terminal-line-19)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r1" x="0" y="508" textLength="134.2" clip-path="url(#terminal-line-20)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="508" textLength="61" clip-path="url(#terminal-line-20)">Type&#160;</text><text class="terminal-r3" x="231.8" y="508" textLength="61" clip-path="url(#terminal-line-20)">/help</text><text class="terminal-r1" x="292.8" y="508" textLength="256.2" clip-path="url(#terminal-line-20)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-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="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="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="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-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)"> </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 transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix"> <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 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="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><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="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="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-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="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-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="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="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="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="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)"> </text><text class="terminal-r1" x="0" y="386" textLength="134.2" clip-path="url(#terminal-line-15)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</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="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="0" y="410.4" textLength="134.2" clip-path="url(#terminal-line-16)">&#160;&#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="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="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="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="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="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="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="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-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)"> </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 transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix"> <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 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="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><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="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="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-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="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="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="288.4" textLength="12.2" clip-path="url(#terminal-line-11)">
</text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)"> </text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)">
@ -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="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="459.2" textLength="146.4" clip-path="url(#terminal-line-18)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="459.2" textLength="122" clip-path="url(#terminal-line-18)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="459.2" textLength="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="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="483.6" textLength="414.8" clip-path="url(#terminal-line-19)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r1" x="0" y="508" textLength="134.2" clip-path="url(#terminal-line-20)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="508" textLength="61" clip-path="url(#terminal-line-20)">Type&#160;</text><text class="terminal-r3" x="231.8" y="508" textLength="61" clip-path="url(#terminal-line-20)">/help</text><text class="terminal-r1" x="292.8" y="508" textLength="256.2" clip-path="url(#terminal-line-20)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-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="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="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="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-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)"> </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 transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix"> <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 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="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><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="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="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-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-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="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="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="288.4" textLength="12.2" clip-path="url(#terminal-line-11)">
</text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)"> </text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)">
</text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)"> </text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)">
</text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)"> </text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)">
</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)"> </text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="0" y="434.8" textLength="134.2" clip-path="url(#terminal-line-17)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="434.8" textLength="146.4" clip-path="url(#terminal-line-17)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="434.8" textLength="122" clip-path="url(#terminal-line-17)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="434.8" textLength="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="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="459.2" textLength="414.8" clip-path="url(#terminal-line-18)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="483.6" textLength="61" clip-path="url(#terminal-line-19)">Type&#160;</text><text class="terminal-r3" x="231.8" y="483.6" textLength="61" clip-path="url(#terminal-line-19)">/help</text><text class="terminal-r1" x="292.8" y="483.6" textLength="256.2" clip-path="url(#terminal-line-19)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-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="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r5" x="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-r1" x="1464" y="630" textLength="12.2" clip-path="url(#terminal-line-25)"> </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="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="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-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)"> </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 transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix"> <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 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="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><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="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-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-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="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="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="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="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="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r1" x="0" y="508" textLength="134.2" clip-path="url(#terminal-line-20)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="508" textLength="146.4" clip-path="url(#terminal-line-20)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="508" textLength="122" clip-path="url(#terminal-line-20)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="508" textLength="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="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r1" x="0" y="532.4" textLength="134.2" clip-path="url(#terminal-line-21)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="532.4" textLength="414.8" clip-path="url(#terminal-line-21)">1&#160;model&#160;·&#160;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="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="0" y="556.8" textLength="134.2" clip-path="url(#terminal-line-22)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="556.8" textLength="61" clip-path="url(#terminal-line-22)">Type&#160;</text><text class="terminal-r3" x="231.8" y="556.8" textLength="61" clip-path="url(#terminal-line-22)">/help</text><text class="terminal-r1" x="292.8" y="556.8" textLength="256.2" clip-path="url(#terminal-line-22)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)"> </text><text class="terminal-r1" x="1464" y="581.2" textLength="12.2" clip-path="url(#terminal-line-23)">
</text><text class="terminal-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r4" x="0" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-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-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="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-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="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="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="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)"> </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 transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix"> <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 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="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><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="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="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="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-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="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="288.4" textLength="12.2" clip-path="url(#terminal-line-11)">
</text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)"> </text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)">
@ -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="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="459.2" textLength="146.4" clip-path="url(#terminal-line-18)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="459.2" textLength="122" clip-path="url(#terminal-line-18)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="459.2" textLength="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="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="483.6" textLength="414.8" clip-path="url(#terminal-line-19)">1&#160;model&#160;·&#160;0&#160;MCP&#160;servers&#160;·&#160;0&#160;skills</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r1" x="0" y="508" textLength="134.2" clip-path="url(#terminal-line-20)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="508" textLength="61" clip-path="url(#terminal-line-20)">Type&#160;</text><text class="terminal-r3" x="231.8" y="508" textLength="61" clip-path="url(#terminal-line-20)">/help</text><text class="terminal-r1" x="292.8" y="508" textLength="256.2" clip-path="url(#terminal-line-20)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)">
</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-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="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="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="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-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)"> </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 transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix"> <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 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="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><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="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-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-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="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="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="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="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="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="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="483.6" textLength="146.4" clip-path="url(#terminal-line-19)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="483.6" textLength="122" clip-path="url(#terminal-line-19)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="483.6" textLength="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="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r1" x="0" y="508" textLength="134.2" clip-path="url(#terminal-line-20)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="508" textLength="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="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r1" x="0" y="532.4" textLength="134.2" clip-path="url(#terminal-line-21)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="532.4" textLength="61" clip-path="url(#terminal-line-21)">Type&#160;</text><text class="terminal-r3" x="231.8" y="532.4" textLength="61" clip-path="url(#terminal-line-21)">/help</text><text class="terminal-r1" x="292.8" y="532.4" textLength="256.2" clip-path="url(#terminal-line-21)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-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-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-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r4" x="0" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-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-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-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-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </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="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="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-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 transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix"> <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 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="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><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="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-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-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-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-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-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-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="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="288.4" textLength="12.2" clip-path="url(#terminal-line-11)">
</text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)"> </text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)">
</text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)"> </text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)">
</text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)"> </text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)">
</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)"> </text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="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="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="0" y="434.8" textLength="134.2" clip-path="url(#terminal-line-17)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</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="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</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="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r4" x="0" y="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-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </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-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-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-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-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-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r4" x="0" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-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-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-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="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="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="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-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 transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix"> <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 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="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><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="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-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-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-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-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-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-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="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="288.4" textLength="12.2" clip-path="url(#terminal-line-11)">
</text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)"> </text><text class="terminal-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-line-12)">
</text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)"> </text><text class="terminal-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-line-13)">
</text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)"> </text><text class="terminal-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-line-14)">
</text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)"> </text><text class="terminal-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-line-15)">
</text><text class="terminal-r1" x="1464" y="410.4" textLength="12.2" clip-path="url(#terminal-line-16)"> </text><text class="terminal-r1" x="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="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="0" y="434.8" textLength="134.2" clip-path="url(#terminal-line-17)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</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="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="0" y="459.2" textLength="134.2" clip-path="url(#terminal-line-18)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</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="483.6" textLength="12.2" clip-path="url(#terminal-line-19)">
</text><text class="terminal-r1" x="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r4" x="0" y="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-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </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-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-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-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-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-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r4" x="0" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-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-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-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="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="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="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-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 transform="translate(9, 41)" clip-path="url(#terminal-clip-terminal)">
<g class="terminal-matrix"> <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 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="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><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="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-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-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="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="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="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="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="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="410.4" textLength="12.2" clip-path="url(#terminal-line-16)">
</text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)"> </text><text class="terminal-r1" x="1464" y="434.8" textLength="12.2" clip-path="url(#terminal-line-17)">
</text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)"> </text><text class="terminal-r1" x="1464" y="459.2" textLength="12.2" clip-path="url(#terminal-line-18)">
</text><text class="terminal-r1" x="1464" y="483.6" textLength="12.2" clip-path="url(#terminal-line-19)"> </text><text class="terminal-r1" x="0" y="483.6" textLength="134.2" clip-path="url(#terminal-line-19)">&#160;&#160;⡠⣒⠄&#160;&#160;⡔⢄⠔⡄</text><text class="terminal-r2" x="170.8" y="483.6" textLength="146.4" clip-path="url(#terminal-line-19)">Mistral&#160;Vibe</text><text class="terminal-r1" x="317.2" y="483.6" textLength="122" clip-path="url(#terminal-line-19)">&#160;v0.0.0&#160;·&#160;</text><text class="terminal-r3" x="439.2" y="483.6" textLength="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="1464" y="508" textLength="12.2" clip-path="url(#terminal-line-20)"> </text><text class="terminal-r1" x="0" y="508" textLength="134.2" clip-path="url(#terminal-line-20)">&#160;⢸⠸⣀⡔⢉⠱⣃⡢⣂⡣</text><text class="terminal-r1" x="170.8" y="508" textLength="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="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)"> </text><text class="terminal-r1" x="0" y="532.4" textLength="134.2" clip-path="url(#terminal-line-21)">&#160;&#160;⠉⠒⠣⠤⠵⠤⠬⠮⠆</text><text class="terminal-r1" x="170.8" y="532.4" textLength="61" clip-path="url(#terminal-line-21)">Type&#160;</text><text class="terminal-r3" x="231.8" y="532.4" textLength="61" clip-path="url(#terminal-line-21)">/help</text><text class="terminal-r1" x="292.8" y="532.4" textLength="256.2" clip-path="url(#terminal-line-21)">&#160;for&#160;more&#160;information</text><text class="terminal-r1" x="1464" y="532.4" textLength="12.2" clip-path="url(#terminal-line-21)">
</text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)"> </text><text class="terminal-r1" x="1464" y="556.8" textLength="12.2" clip-path="url(#terminal-line-22)">
</text><text class="terminal-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-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-r1" x="1464" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"> </text><text class="terminal-r4" x="0" y="605.6" textLength="12.2" clip-path="url(#terminal-line-24)"></text><text class="terminal-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-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-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-r1" x="1464" y="654.4" textLength="12.2" clip-path="url(#terminal-line-26)"> </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="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="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-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 @pytest.mark.asyncio
async def test_act_streams_batched_chunks_in_order() -> None: async def test_act_streams_chunks_in_order() -> None:
backend = FakeBackend([ backend = FakeBackend([
mock_llm_chunk(content="Hello"), mock_llm_chunk(content="Hello"),
mock_llm_chunk(content=" from"), 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.")] events = [event async for event in agent.act("Stream, please.")]
assistant_events = [e for e in events if isinstance(e, AssistantEvent)] 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] == [ assert [event.content for event in assistant_events] == [
"Hello from Vibe! More", "Hello",
" and end", " from",
" Vibe",
"! ",
"More",
" and",
" end",
] ]
assert agent.messages[-1].role == Role.assistant assert agent.messages[-1].role == Role.assistant
assert agent.messages[-1].content == "Hello from Vibe! More and end" 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] == [ assert [type(event) for event in events] == [
UserMessageEvent, UserMessageEvent,
AssistantEvent, AssistantEvent,
AssistantEvent,
AssistantEvent,
ToolCallEvent, ToolCallEvent,
ToolResultEvent, ToolResultEvent,
] ]
assert isinstance(events[0], UserMessageEvent) assert isinstance(events[0], UserMessageEvent)
assert isinstance(events[1], AssistantEvent) 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( assert any(
m.role == Role.assistant and m.content == "Preparing todo request complete" m.role == Role.assistant and m.content == "Preparing todo request complete"
for m in agent.messages 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] == [ assert [type(event) for event in events] == [
UserMessageEvent, UserMessageEvent,
AssistantEvent, AssistantEvent,
AssistantEvent,
ToolCallEvent, ToolCallEvent,
ToolResultEvent, ToolResultEvent,
] ]
@ -430,7 +442,7 @@ def _snapshot_events(events: list) -> list[tuple[str, str]]:
@pytest.mark.asyncio @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([ backend = FakeBackend([
mock_llm_chunk(content="", reasoning_content="Let me think"), mock_llm_chunk(content="", reasoning_content="Let me think"),
mock_llm_chunk(content="", reasoning_content=" about this"), 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?")] events = [event async for event in agent.act("What's the answer?")]
assert _snapshot_events(events) == [ 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."), ("AssistantEvent", "The answer is 42."),
] ]
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_reasoning_buffer_yields_before_content_with_batching() -> None: async def test_reasoning_yields_per_chunk() -> None:
backend = FakeBackend([ backend = FakeBackend([
mock_llm_chunk(content="", reasoning_content="Step 1"), mock_llm_chunk(content="", reasoning_content="Step 1"),
mock_llm_chunk(content="", reasoning_content=", Step 2"), mock_llm_chunk(content="", reasoning_content=", Step 2"),
mock_llm_chunk(content="", reasoning_content=", Step 3"), mock_llm_chunk(content="", reasoning_content=", Step 3"),
mock_llm_chunk(content="", reasoning_content=", Step 4"), 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=", Step 6"),
mock_llm_chunk(content="", reasoning_content=", Final"), mock_llm_chunk(content="", reasoning_content=", Final"),
mock_llm_chunk(content="Done thinking!"), 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")] events = [event async for event in agent.act("Think step by step")]
assert _snapshot_events(events) == [ assert _snapshot_events(events) == [
("ReasoningEvent", "Step 1, Step 2, Step 3, Step 4, Step 5"), ("ReasoningEvent", "Step 1"),
("ReasoningEvent", ", Step 6, Final"), ("ReasoningEvent", ", Step 2"),
("ReasoningEvent", ", Step 3"),
("ReasoningEvent", ", Step 4"),
("ReasoningEvent", ", Step 5"),
("ReasoningEvent", ", Step 6"),
("ReasoningEvent", ", Final"),
("AssistantEvent", "Done thinking!"), ("AssistantEvent", "Done thinking!"),
] ]
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_content_buffer_yields_before_reasoning_on_transition() -> None: async def test_content_yields_before_reasoning_on_transition() -> None:
"""When content is buffered and reasoning arrives, content yields first.""" """When content chunks arrive and reasoning arrives, content yields first."""
backend = FakeBackend([ backend = FakeBackend([
mock_llm_chunk(content="Starting the response"), mock_llm_chunk(content="Starting the response"),
mock_llm_chunk(content=" here..."), 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")] events = [event async for event in agent.act("Give me an answer")]
assert _snapshot_events(events) == [ assert _snapshot_events(events) == [
("AssistantEvent", "Starting the response here..."), ("AssistantEvent", "Starting the response"),
("ReasoningEvent", "Wait, let me reconsider this approach..."), ("AssistantEvent", " here..."),
("ReasoningEvent", "Wait, let me reconsider"),
("ReasoningEvent", " this approach..."),
("AssistantEvent", "Actually, the final answer."), ("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")] events = [event async for event in agent.act("Silent thinking")]
assert _snapshot_events(events) == [ 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: async def test_empty_content_chunks_do_not_trigger_false_yields() -> None:
backend = FakeBackend([ backend = FakeBackend([
mock_llm_chunk(content="", reasoning_content="Reasoning here"), 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="", reasoning_content=" more reasoning"),
mock_llm_chunk(content="Actual content"), 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")] events = [event async for event in agent.act("Empty content test")]
assert _snapshot_events(events) == [ assert _snapshot_events(events) == [
("ReasoningEvent", "Reasoning here more reasoning"), ("ReasoningEvent", "Reasoning here"),
("ReasoningEvent", " more reasoning"),
("AssistantEvent", "Actual content"), ("AssistantEvent", "Actual content"),
] ]

View file

@ -535,6 +535,27 @@ class TestAutoCompactIntegration:
class TestClearHistoryFullReset: 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 @pytest.mark.asyncio
async def test_clear_history_fully_resets_stats(self) -> None: async def test_clear_history_fully_resets_stats(self) -> None:
backend = FakeBackend(mock_llm_chunk(content="Response")) backend = FakeBackend(mock_llm_chunk(content="Response"))

View file

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

4
uv.lock generated
View file

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

View file

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

View file

@ -1,8 +1,12 @@
from __future__ import annotations from __future__ import annotations
import base64 import base64
from collections.abc import Callable
import os import os
import shutil
import subprocess
import pyperclip
from textual.app import App from textual.app import App
_PREVIEW_MAX_LENGTH = 40 _PREVIEW_MAX_LENGTH = 40
@ -19,6 +23,100 @@ def _copy_osc52(text: str) -> None:
tty.flush() 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: def _shorten_preview(texts: list[str]) -> str:
dense_text = "".join(texts).replace("\n", "") dense_text = "".join(texts).replace("\n", "")
if len(dense_text) > _PREVIEW_MAX_LENGTH: if len(dense_text) > _PREVIEW_MAX_LENGTH:
@ -26,7 +124,7 @@ def _shorten_preview(texts: list[str]) -> str:
return dense_text 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 = [] selected_texts = []
for widget in app.query("*"): 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(): if selected_text.strip():
selected_texts.append(selected_text) 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: if not selected_texts:
return None return None
combined_text = "\n".join(selected_texts) combined_text = "\n".join(selected_texts)
try: try:
_copy_osc52(combined_text) _copy_to_clipboard(combined_text)
if show_toast: if show_toast:
app.notify( app.notify(
f'"{_shorten_preview(selected_texts)}" copied to clipboard', f'"{_shorten_preview(selected_texts)}" copied to clipboard',

View file

@ -2,16 +2,20 @@ from __future__ import annotations
import asyncio import asyncio
from enum import StrEnum, auto from enum import StrEnum, auto
import os
from pathlib import Path from pathlib import Path
import signal
import subprocess import subprocess
import time import time
from typing import Any, ClassVar, assert_never, cast from typing import Any, ClassVar, assert_never, cast
from weakref import WeakKeyDictionary from weakref import WeakKeyDictionary
from pydantic import BaseModel 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.binding import Binding, BindingType
from textual.containers import Horizontal, VerticalGroup, VerticalScroll from textual.containers import Horizontal, VerticalGroup, VerticalScroll
from textual.driver import Driver
from textual.events import AppBlur, AppFocus, MouseUp from textual.events import AppBlur, AppFocus, MouseUp
from textual.widget import Widget from textual.widget import Widget
from textual.widgets import Static 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.load_more import HistoryLoadMoreRequested
from vibe.cli.textual_ui.widgets.loading import LoadingWidget, paused_timer from vibe.cli.textual_ui.widgets.loading import LoadingWidget, paused_timer
from vibe.cli.textual_ui.widgets.messages import ( from vibe.cli.textual_ui.widgets.messages import (
AssistantMessage,
BashOutputMessage, BashOutputMessage,
ErrorMessage, ErrorMessage,
InterruptMessage, InterruptMessage,
ReasoningMessage,
StreamingMessageBase, StreamingMessageBase,
UserCommandMessage, UserCommandMessage,
UserMessage, 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.proxy_setup_app import ProxySetupApp
from vibe.cli.textual_ui.widgets.question_app import QuestionApp 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.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 ( from vibe.cli.textual_ui.windowing import (
HISTORY_RESUME_TAIL_MESSAGES, HISTORY_RESUME_TAIL_MESSAGES,
LOAD_MORE_BATCH_SIZE, LOAD_MORE_BATCH_SIZE,
@ -180,6 +182,7 @@ class VibeApp(App): # noqa: PLR0904
BINDINGS: ClassVar[list[BindingType]] = [ BINDINGS: ClassVar[list[BindingType]] = [
Binding("ctrl+c", "clear_quit", "Quit", show=False), Binding("ctrl+c", "clear_quit", "Quit", show=False),
Binding("ctrl+d", "force_quit", "Quit", show=False, priority=True), 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("escape", "interrupt", "Interrupt", show=False, priority=True),
Binding("ctrl+o", "toggle_tool", "Toggle Tool", show=False), Binding("ctrl+o", "toggle_tool", "Toggle Tool", show=False),
Binding("ctrl+y", "copy_selection", "Copy", show=False, priority=True), 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.history_file = HISTORY_FILE.path
self._tools_collapsed = True 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._windowing = SessionWindowing(load_more_batch_size=LOAD_MORE_BATCH_SIZE)
self._load_more = HistoryLoadMoreManager() self._load_more = HistoryLoadMoreManager()
self._tool_call_map: dict[str, str] | None = None 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._plan_offer_gateway = plan_offer_gateway
self._initial_prompt = initial_prompt self._initial_prompt = initial_prompt
self._teleport_on_start = teleport_on_start and self.config.nuage_enabled self._teleport_on_start = teleport_on_start and self.config.nuage_enabled
self._auto_scroll = True
self._last_escape_time: float | None = None self._last_escape_time: float | None = None
self._banner: Banner | None = None self._banner: Banner | None = None
self._whats_new_message: WhatsNewMessage | None = None
self._cached_messages_area: Widget | None = None self._cached_messages_area: Widget | None = None
self._cached_chat: ChatScroll | None = None self._cached_chat: ChatScroll | None = None
self._cached_loading_area: Widget | 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, safety=self.agent_loop.agent_profile.safety,
agent_name=self.agent_loop.agent_profile.display_name.lower(), agent_name=self.agent_loop.agent_profile.display_name.lower(),
skill_entries_getter=self._get_skill_entries, skill_entries_getter=self._get_skill_entries,
file_watcher_for_autocomplete_getter=self._is_file_watcher_enabled,
nuage_enabled=self.config.nuage_enabled, nuage_enabled=self.config.nuage_enabled,
) )
@ -284,7 +286,6 @@ class VibeApp(App): # noqa: PLR0904
self.event_handler = EventHandler( self.event_handler = EventHandler(
mount_callback=self._mount_and_scroll, mount_callback=self._mount_and_scroll,
scroll_callback=self._scroll_to_bottom_deferred,
get_tools_collapsed=lambda: self._tools_collapsed, get_tools_collapsed=lambda: self._tools_collapsed,
) )
@ -312,6 +313,8 @@ class VibeApp(App): # noqa: PLR0904
self._schedule_update_notification() self._schedule_update_notification()
self.agent_loop.emit_new_session_telemetry("cli") self.agent_loop.emit_new_session_telemetry("cli")
self.call_after_refresh(self._refresh_banner)
if self._initial_prompt or self._teleport_on_start: if self._initial_prompt or self._teleport_on_start:
self.call_after_refresh(self._process_initial_prompt) 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 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( async def on_chat_input_container_submitted(
self, event: ChatInputContainer.Submitted self, event: ChatInputContainer.Submitted
) -> None: ) -> None:
if self._banner: if self._banner:
self._banner.freeze_animation() self._banner.freeze_animation()
if self._whats_new_message:
await self._whats_new_message.remove()
self._whats_new_message = None
value = event.value.strip() value = event.value.strip()
if not value: if not value:
return return
@ -582,9 +592,7 @@ class VibeApp(App): # noqa: PLR0904
plan.tool_call_map, plan.tool_call_map,
start_index=plan.tail_start_index, start_index=plan.tail_start_index,
) )
self.call_after_refresh( self.call_after_refresh(self._scroll_chat_to_end)
lambda: self._align_chat_after_history_rebuild(plan.has_backfill)
)
self._tool_call_map = plan.tool_call_map self._tool_call_map = plan.tool_call_map
self._windowing.set_backfill(plan.backfill_messages) self._windowing.set_backfill(plan.backfill_messages)
await self._load_more.set_visible( await self._load_more.set_visible(
@ -703,7 +711,8 @@ class VibeApp(App): # noqa: PLR0904
if self._loading_widget: if self._loading_widget:
await self._loading_widget.remove() await self._loading_widget.remove()
self._loading_widget = None 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() await self._refresh_windowing_from_history()
async def _teleport_command(self) -> None: async def _teleport_command(self) -> None:
@ -814,6 +823,7 @@ class VibeApp(App): # noqa: PLR0904
if self.event_handler: if self.event_handler:
self.event_handler.stop_current_tool_call(success=False) self.event_handler.stop_current_tool_call(success=False)
self.event_handler.stop_current_compact() self.event_handler.stop_current_compact()
await self.event_handler.finalize_streaming()
self._agent_running = False self._agent_running = False
loading_area = self._cached_loading_area or self.query_one( loading_area = self._cached_loading_area or self.query_one(
@ -822,7 +832,6 @@ class VibeApp(App): # noqa: PLR0904
await loading_area.remove_children() await loading_area.remove_children()
self._loading_widget = None self._loading_widget = None
await self._finalize_current_streaming_message()
await self._mount_and_scroll(InterruptMessage()) await self._mount_and_scroll(InterruptMessage())
self._interrupt_requested = False self._interrupt_requested = False
@ -881,7 +890,8 @@ class VibeApp(App): # noqa: PLR0904
self._tool_call_map = None self._tool_call_map = None
self._history_widget_indices = WeakKeyDictionary() self._history_widget_indices = WeakKeyDictionary()
await self.agent_loop.clear_history() 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") messages_area = self._cached_messages_area or self.query_one("#messages")
await messages_area.remove_children() await messages_area.remove_children()
@ -1019,7 +1029,7 @@ class VibeApp(App): # noqa: PLR0904
self.call_after_refresh(widget.focus) self.call_after_refresh(widget.focus)
if scroll: 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: async def _switch_to_config_app(self) -> None:
if self._current_bottom_app == BottomApp.Config: if self._current_bottom_app == BottomApp.Config:
@ -1059,7 +1069,7 @@ class VibeApp(App): # noqa: PLR0904
self._chat_input_container.display = True self._chat_input_container.display = True
self._current_bottom_app = BottomApp.Input self._current_bottom_app = BottomApp.Input
self.call_after_refresh(self._chat_input_container.focus_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: def _focus_current_bottom_app(self) -> None:
try: try:
@ -1153,7 +1163,7 @@ class VibeApp(App): # noqa: PLR0904
self._handle_agent_running_escape() self._handle_agent_running_escape()
self._last_escape_time = current_time self._last_escape_time = current_time
self._scroll_to_bottom() self.call_after_refresh(self._scroll_chat_to_end)
self._focus_current_bottom_app() self._focus_current_bottom_app()
async def on_history_load_more_requested(self, _: HistoryLoadMoreRequested) -> None: 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: def _refresh_profile_widgets(self) -> None:
self._update_profile_widgets(self.agent_loop.agent_profile) 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: def _update_profile_widgets(self, profile: AgentProfile) -> None:
if self._chat_input_container: if self._chat_input_container:
self._chat_input_container.set_safety(profile.safety) self._chat_input_container.set_safety(profile.safety)
@ -1245,7 +1259,6 @@ class VibeApp(App): # noqa: PLR0904
try: try:
chat = self._cached_chat or self.query_one("#chat", ChatScroll) chat = self._cached_chat or self.query_one("#chat", ChatScroll)
chat.scroll_relative(y=-5, animate=False) chat.scroll_relative(y=-5, animate=False)
self._auto_scroll = False
except Exception: except Exception:
pass pass
@ -1253,8 +1266,6 @@ class VibeApp(App): # noqa: PLR0904
try: try:
chat = self._cached_chat or self.query_one("#chat", ChatScroll) chat = self._cached_chat or self.query_one("#chat", ChatScroll)
chat.scroll_relative(y=5, animate=False) chat.scroll_relative(y=5, animate=False)
if self._is_scrolled_to_bottom(chat):
self._auto_scroll = True
except Exception: except Exception:
pass pass
@ -1283,7 +1294,11 @@ class VibeApp(App): # noqa: PLR0904
whats_new_message = WhatsNewMessage(f"{content}\n\n{plan_offer}") whats_new_message = WhatsNewMessage(f"{content}\n\n{plan_offer}")
if self._history_widget_indices: if self._history_widget_indices:
whats_new_message.add_class("after-history") 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) await mark_version_as_seen(self._current_version, self._update_cache_repository)
async def _plan_offer_cta(self) -> str | None: async def _plan_offer_cta(self) -> str | None:
@ -1309,105 +1324,29 @@ class VibeApp(App): # noqa: PLR0904
) )
return return
async def _finalize_current_streaming_message(self) -> None: def _scroll_chat_to_end(self) -> None:
if self._current_streaming_reasoning is not None: chat = self._cached_chat or self.query_one("#chat", ChatScroll)
self._current_streaming_reasoning.stop_spinning() chat.scroll_end(animate=False)
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
async def _mount_and_scroll(self, widget: Widget) -> None: async def _mount_and_scroll(self, widget: Widget) -> None:
messages_area = self._cached_messages_area or self.query_one("#messages") messages_area = self._cached_messages_area or self.query_one("#messages")
chat = self._cached_chat or self.query_one("#chat", ChatScroll) 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: await messages_area.mount(widget)
self._auto_scroll = True if isinstance(widget, StreamingMessageBase):
await widget.write_initial_content()
if isinstance(widget, ReasoningMessage): self.call_after_refresh(self._try_prune)
result = await self._handle_streaming_widget( chat.anchor()
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)
async def _try_prune(self) -> None: async def _try_prune(self) -> None:
messages_area = self._cached_messages_area or self.query_one("#messages") 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: if self._load_more.widget and not self._load_more.widget.parent:
self._load_more.widget = None 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: async def _refresh_windowing_from_history(self) -> None:
if self._load_more.widget is 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 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: def _schedule_update_notification(self) -> None:
if self._update_notifier is None or not self.config.enable_update_checks: if self._update_notifier is None or not self.config.enable_update_checks:
return return
@ -1516,6 +1432,20 @@ class VibeApp(App): # noqa: PLR0904
if self._chat_input_container and self._chat_input_container.input_widget: if self._chat_input_container and self._chat_input_container.input_widget:
self._chat_input_container.input_widget.set_app_focus(True) 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: def _print_session_resume_message(session_id: str | None) -> None:
if not session_id: if not session_id:

View file

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

View file

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

View file

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

View file

@ -63,6 +63,12 @@ class ConfigApp(Container):
"type": "cycle", "type": "cycle",
"options": ["On", "Off"], "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 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]: def _truncate_lines(content: str, max_lines: int) -> tuple[str, str | None]:
"""Truncate content to max_lines, returning (content, truncation_info).""" """Truncate content to max_lines, returning (content, truncation_info)."""
lines = content.split("\n") lines = content.strip("\n").split("\n")
if len(lines) <= max_lines: if len(lines) <= max_lines:
return content, None return "\n".join(lines), None
remaining = len(lines) - max_lines remaining = len(lines) - max_lines
return "\n".join(lines[:max_lines]), f"… ({remaining} more 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 textual.widget import Widget
from vibe.cli.textual_ui.widgets.messages import WhatsNewMessage
from vibe.cli.textual_ui.windowing.history import ( from vibe.cli.textual_ui.windowing.history import (
build_tool_call_map, build_tool_call_map,
split_history_tail, split_history_tail,
@ -29,10 +28,7 @@ class HistoryResumePlan:
def should_resume_history(messages_children: list[Widget]) -> bool: def should_resume_history(messages_children: list[Widget]) -> bool:
allowed_pre_existing_types = (WhatsNewMessage,) return len(messages_children) == 0
return all(
isinstance(child, allowed_pre_existing_types) for child in messages_children
)
def create_resume_plan( def create_resume_plan(

View file

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

View file

@ -71,8 +71,9 @@ class PathCompleter(Completer):
self, self,
max_entries_to_process: int = DEFAULT_MAX_ENTRIES_TO_PROCESS, max_entries_to_process: int = DEFAULT_MAX_ENTRIES_TO_PROCESS,
target_matches: int = DEFAULT_TARGET_MATCHES, target_matches: int = DEFAULT_TARGET_MATCHES,
watcher_enabled_getter: Callable[[], bool] | None = 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._max_entries_to_process = max_entries_to_process
self._target_matches = target_matches self._target_matches = target_matches

View file

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

View file

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

View file

@ -9,6 +9,7 @@ from typing import TYPE_CHECKING, NamedTuple, cast
import httpx import httpx
import mistralai import mistralai
from mistralai.utils.retries import BackoffStrategy, RetryConfig
from vibe.core.llm.exceptions import BackendErrorBuilder from vibe.core.llm.exceptions import BackendErrorBuilder
from vibe.core.llm.message_utils import merge_consecutive_user_messages from vibe.core.llm.message_utils import merge_consecutive_user_messages
@ -178,13 +179,22 @@ class MistralBackend:
) )
self._server_url = match.group(1) self._server_url = match.group(1)
self._timeout = timeout 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: async def __aenter__(self) -> MistralBackend:
self._client = mistralai.Mistral( self._client = self._create_mistral_client()
api_key=self._api_key,
server_url=self._server_url,
timeout_ms=int(self._timeout * 1000),
)
await self._client.__aenter__() await self._client.__aenter__()
return self return self
@ -199,11 +209,17 @@ class MistralBackend:
exc_type=exc_type, exc_val=exc_val, exc_tb=exc_tb 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: def _get_client(self) -> mistralai.Mistral:
if self._client is None: if self._client is None:
self._client = mistralai.Mistral( self._client = self._create_mistral_client()
api_key=self._api_key, server_url=self._server_url
)
return self._client return self._client
async def complete( async def complete(

View file

@ -1,9 +1,11 @@
from __future__ import annotations from __future__ import annotations
import json import json
import threading
from typing import Any, ClassVar from typing import Any, ClassVar
import google.auth import google.auth
import google.auth.credentials
from google.auth.transport.requests import Request from google.auth.transport.requests import Request
from vibe.core.config import ProviderConfig 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 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: def build_vertex_base_url(region: str) -> str:
if region == "global": if region == "global":
return "https://aiplatform.googleapis.com" 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): class VertexAnthropicAdapter(AnthropicAdapter):
"""Vertex AI adapter — inherits all streaming/parsing from AnthropicAdapter.""" """Vertex AI adapter — inherits all streaming/parsing from AnthropicAdapter."""
endpoint: ClassVar[str] = "" endpoint: ClassVar[str] = ""
# Vertex AI doesn't support beta features
BETA_FEATURES: ClassVar[str] = "" BETA_FEATURES: ClassVar[str] = ""
def __init__(self) -> None:
super().__init__()
self.credentials = VertexCredentials()
def prepare_request( # noqa: PLR0913 def prepare_request( # noqa: PLR0913
self, self,
*, *,
@ -70,7 +89,6 @@ class VertexAnthropicAdapter(AnthropicAdapter):
converted_tools = self._mapper.prepare_tools(tools) converted_tools = self._mapper.prepare_tools(tools)
converted_tool_choice = self._mapper.prepare_tool_choice(tool_choice) converted_tool_choice = self._mapper.prepare_tool_choice(tool_choice)
# Build vertex-specific payload (no "model" key, uses anthropic_version)
payload: dict[str, Any] = { payload: dict[str, Any] = {
"anthropic_version": "vertex-2023-10-16", "anthropic_version": "vertex-2023-10-16",
"messages": converted_messages, "messages": converted_messages,
@ -98,11 +116,9 @@ class VertexAnthropicAdapter(AnthropicAdapter):
self._add_cache_control_to_last_user_message(converted_messages) self._add_cache_control_to_last_user_message(converted_messages)
access_token = get_vertex_access_token()
headers = { headers = {
"Content-Type": "application/json", "Content-Type": "application/json",
"Authorization": f"Bearer {access_token}", "Authorization": f"Bearer {self.credentials.access_token}",
"anthropic-beta": self.BETA_FEATURES, "anthropic-beta": self.BETA_FEATURES,
} }

View file

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

View file

@ -61,6 +61,12 @@ class AgentStats(BaseModel):
) -> None: ) -> None:
self._listeners[attr_name] = listener self._listeners[attr_name] = listener
@staticmethod
def create_fresh(previous: AgentStats) -> AgentStats:
fresh = AgentStats()
fresh._listeners = previous._listeners.copy()
return fresh
@computed_field @computed_field
@property @property
def session_total_llm_tokens(self) -> int: 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/`. - **Performance**: general improvements (streaming, scrolling).
- **Fix**: autocopying now behaves correctly in cases where it previously failed.
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.