Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package mistral-vibe for openSUSE:Factory 
checked in at 2026-09-28 10:45:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/mistral-vibe (Old)
 and      /work/SRC/openSUSE:Factory/.mistral-vibe.new.383539 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "mistral-vibe"

Mon Sep 28 10:45:27 2026 rev:22 rq:1380774 version:2.25.8

Changes:
--------
--- /work/SRC/openSUSE:Factory/mistral-vibe/mistral-vibe.changes        
2026-09-14 16:22:45.215503230 +0200
+++ /work/SRC/openSUSE:Factory/.mistral-vibe.new.383539/mistral-vibe.changes    
2026-09-28 10:45:47.118275042 +0200
@@ -1,0 +2,63 @@
+Thu Sep 24 09:35:11 UTC 2026 - Martin Pluskal <[email protected]>
+
+- Update to 2.25.8 (includes 2.25.7):
+  * Remote Vibe Code project configuration, session
+    archiving with unseen indicators, pinned live todo plan
+  * Plugin MCP servers start so their tools are callable;
+    sessionless MCP add/remove, caret-aware completion
+  * /leanstall works on the unified backend without TUI
+    crashes; clean exit on terminal disconnect
+  * Hardened Git handling: automatic project context no longer
+    runs repository-configured clean or process filters, and
+    repository inspection, worktree setup, fetches and teleport
+    diffs no longer honour repository-controlled Git
+    executables, hooks, helpers or configuration. Worktree
+    operations disable core.hooksPath, so a repository's own
+    hooks can no longer run before trust validation
+    (CVE-2026-93993, boo#1282078)
+  * The Vibe home, prompt history, debug log and trust store are
+    now created owner-only, and the home plus existing session
+    logs are tightened at startup; ACP workspace-trust decisions
+    require a session and cannot target another directory
+  * Shell approvals no longer widen across programs,
+    subcommands, redirections or line continuations, and
+    WebFetch asks again before following a redirect to another
+    origin
+  * vibe mcp add --allow-insecure-http and /mcp add
+    --allow-insecure-http opt into plaintext http:// MCP servers
+    on non-localhost hosts
+  * /mcp login now fails loudly when a server never issues an
+    OAuth challenge, instead of reporting a false success
+  * Config layers merge key by key, so setting one nested value
+    no longer discards the rest of that group
+  * Sessions reopen on their last model and thinking level,
+    open much faster with many git worktrees, and path
+    completion no longer inserts stale suggestions
+  * /teleport accepts Vibe and workspace API keys, including on
+    free accounts, and says which key to use when it rejects one
+  * Many more fixes and improvements; see upstream's release
+    notes for the full list
+- Add build_system_hatchling.patch: upstream now builds a PyO3
+  extension with maturin, whose v8 crate downloads a toolchain at
+  build time; keep building the pure-Python tree with hatchling
+- Add harness_optional_import.patch: keep the optional Unified
+  Harness distribution off the legacy app-server import path,
+  which otherwise fails to import without it
+- Add app_server_turn_timeouts.patch: one-second asyncio waits in
+  the turn tests expire on a loaded build worker
+- Add greeting_startup_race.patch: the startup worker raised out
+  of Textual when the chat widget was not on screen yet
+- Refresh the carried patches for 2.25.7 and extend
+  harness_importorskip.patch to the test modules that now import
+  the harness at module scope
+- Run test_respects_max_entries_to_process_limit again: the
+  upstream race that made it fail is gone
+- Delete vibe/cli-rust and client-e2e after unpacking: the Rust
+  front-end declares its own "Proprietary" license in Cargo.toml
+  and neither tree is built or shipped
+- Drop python3-sounddevice: upstream switched the audio engine to
+  miniaudio, which Factory does not carry, so voice recording and
+  playback are no longer available
+- Require python3-GitPython >= 3.1.61
+
+-------------------------------------------------------------------

Old:
----
  mistral-vibe-2.25.4.tar.gz

New:
----
  app_server_turn_timeouts.patch
  build_system_hatchling.patch
  greeting_startup_race.patch
  harness_optional_import.patch
  mistral-vibe-2.25.8.tar.gz

----------(New B)----------
  New:  which otherwise fails to import without it
- Add app_server_turn_timeouts.patch: one-second asyncio waits in
  the turn tests expire on a loaded build worker
  New:    notes for the full list
- Add build_system_hatchling.patch: upstream now builds a PyO3
  extension with maturin, whose v8 crate downloads a toolchain at
  New:  the turn tests expire on a loaded build worker
- Add greeting_startup_race.patch: the startup worker raised out
  of Textual when the chat widget was not on screen yet
  New:  build time; keep building the pure-Python tree with hatchling
- Add harness_optional_import.patch: keep the optional Unified
  Harness distribution off the legacy app-server import path,
----------(New E)----------

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ mistral-vibe.spec ++++++
--- /var/tmp/diff_new_pack.km2hhE/_old  2026-09-28 10:45:49.564377525 +0200
+++ /var/tmp/diff_new_pack.km2hhE/_new  2026-09-28 10:45:49.568377692 +0200
@@ -28,9 +28,16 @@
 %endif
 %define origname mistral-vibe
 Name:           %{origname}%{psuffix}
-Version:        2.25.4
+Version:        2.25.8
 Release:        0
 Summary:        Minimal CLI coding agent by Mistral
+# Legal-Review-Notice: vibe/cli-rust is not built and not shipped.  It is an
+# alternative Rust front-end whose own Cargo.toml declares license =
+# "Proprietary", while the repository LICENSE and the [project] metadata both
+# say Apache-2.0.  Nothing here compiles or installs it: the directory is
+# deleted right after the sources are unpacked and the wheel configuration
+# excludes it, so every file in the binary packages comes from the
+# Apache-2.0 Python tree.
 License:        Apache-2.0
 URL:            https://github.com/mistralai/mistral-vibe
 Source0:        
https://github.com/mistralai/mistral-vibe/archive/refs/tags/v%{version}.tar.gz#/mistral-vibe-%{version}.tar.gz
@@ -60,9 +67,22 @@
 # invisible to the file fingerprint; hash the contents too
 Patch7:         fingerprint_file_contents.patch
 # PATCH-FIX-UPSTREAM harness_importorskip.patch [email protected]
-# the harness is an optional extra: skip the module when it is missing
-# instead of failing collection, same as the other harness test modules
+# the harness is an optional extra: skip the modules that import it at module
+# scope instead of failing collection, same as upstream's own harness guards
 Patch8:         harness_importorskip.patch
+# PATCH-FIX-UPSTREAM harness_optional_import.patch [email protected]
+# keep the optional harness distribution off the legacy app-server import path
+Patch9:         harness_optional_import.patch
+# PATCH-FIX-OPENSUSE build_system_hatchling.patch [email protected]
+# upstream builds a PyO3 extension with maturin, whose v8 crate downloads a
+# toolchain at build time; build the pure-Python tree with hatchling instead
+Patch10:        build_system_hatchling.patch
+# PATCH-FIX-OPENSUSE app_server_turn_timeouts.patch [email protected]
+# one-second asyncio waits time out under the parallel run on a busy worker
+Patch11:        app_server_turn_timeouts.patch
+# PATCH-FIX-UPSTREAM greeting_startup_race.patch [email protected]
+# the post-ready worker must not raise when the chat widget is not on screen
+Patch12:        greeting_startup_race.patch
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
 BuildRequires:  python3-base >= 3.12
@@ -73,7 +93,7 @@
 BuildRequires:  python3-rfc8785 >= 0.1.4
 BuildArch:      noarch
 %if !%{with test}
-Requires:       python3-GitPython >= 3.1.57
+Requires:       python3-GitPython >= 3.1.61
 Requires:       python3-PyJWT >= 2.13.0
 Requires:       python3-PyYAML >= 6.0.3
 Requires:       python3-SecretStorage >= 3.5.0
@@ -149,7 +169,6 @@
 Requires:       python3-setproctitle >= 1.3.7
 Requires:       python3-six >= 1.17.0
 Requires:       python3-smmap >= 5.0.3
-Requires:       python3-sounddevice >= 0.5.5
 Requires:       python3-soupsieve >= 2.8.4
 Requires:       python3-sse-starlette >= 3.4.1
 Requires:       python3-starlette >= 1.3.1
@@ -180,7 +199,7 @@
 %if %{with test}
 BuildRequires:  ca-certificates
 BuildRequires:  ca-certificates-mozilla
-BuildRequires:  python3-GitPython >= 3.1.57
+BuildRequires:  python3-GitPython >= 3.1.61
 BuildRequires:  python3-Jinja2
 BuildRequires:  python3-PyJWT >= 2.13.0
 BuildRequires:  python3-PyYAML >= 6.0.3
@@ -259,7 +278,6 @@
 BuildRequires:  python3-rpds-py >= 0.30.0
 BuildRequires:  python3-sentry-sdk >= 2.64.0
 BuildRequires:  python3-setproctitle >= 1.3.7
-BuildRequires:  python3-sounddevice >= 0.5.5
 BuildRequires:  python3-soupsieve >= 2.8.4
 BuildRequires:  python3-sse-starlette >= 3.4.1
 BuildRequires:  python3-starlette >= 1.3.1
@@ -293,6 +311,9 @@
 
 %prep
 %autosetup -p1 -n %{origname}-%{version}
+# not built, not shipped: cli-rust declares its own "Proprietary" license and
+# client-e2e is a standalone suite upstream excludes from this project's pytest
+rm -rf vibe/cli-rust client-e2e
 
 %build
 %python3_pyproject_wheel
@@ -313,10 +334,16 @@
 PYTEST_ADDOPTS="--ignore=tests/audio_player/test_audio_player.py --timeout=60 
-n 4"
 export PYTEST_ADDOPTS+=" --ignore=tests/audio_recorder/test_audio_recorder.py"
 export PYTEST_ADDOPTS+=" --ignore=tests/snapshots"
-# -k deselects: the ssl_cert_file test needs network certs; the
-# max_entries test races scandir walk order against the processing
-# cap and fails with an empty assertion set (upstream 2.25.3 race).
-%python3_pytest -m 'not (network or terminal)' -k 'not 
test_generic_backend_streaming_uses_ssl_cert_file and not 
test_respects_max_entries_to_process_limit'
+# The ssl_cert_file test drives a TLS mock server over a real socket; the
+# request never completes here and the test only ends when pytest-timeout
+# kills it, so deselect it.
+# Twelve tests need the experimental harness (mistralai_vibe_local_harness,
+# a Rust extension built from harness/ and not shipped in this wheel):
+# ten resolve_agent_types tests import its protocol types at runtime, and
+# two expect its stubbed (not absent) import error. Deselect them.
+# (test_respects_max_entries_to_process_limit was deselected until 2.25.7
+# for an upstream race; it passes again.)
+%python3_pytest -m 'not (network or terminal)' -k 'not 
test_generic_backend_streaming_uses_ssl_cert_file and not 
test_a_project_subagent_is_advertised_and_bound and not 
test_explicit_instructions_win_over_a_named_prompt and not 
test_a_subagent_with_no_prompt_inherits_the_parents and not 
test_a_tool_the_profile_disables_is_denied_to_the_child and not 
test_the_advertised_half_alone_needs_no_tool_catalogue and not 
test_a_tool_the_profile_disables_is_not_reported_as_downgraded and not 
test_an_agent_file_that_shadows_explore_is_advertised and not 
test_a_granted_tool_narrowed_by_an_allowlist_is_capped_at_ask and not 
test_a_named_prompt_becomes_the_prompt_the_child_runs_on and not 
test_a_granted_tool_with_no_list_stays_granted and not 
test_available_experimental_harness_never_opens_a_legacy_runtime and not 
test_a_host_that_cannot_take_builtin_hooks_falls_back_to_legacy'
 %endif
 
 %if !%{with test}

++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.km2hhE/_old  2026-09-28 10:45:49.742384982 +0200
+++ /var/tmp/diff_new_pack.km2hhE/_new  2026-09-28 10:45:49.758385653 +0200
@@ -1,5 +1,5 @@
-mtime: 1789319620
-commit: ef25ca8d7a609d354780161982786da34888317bf5d41e677dea43f769268b97
+mtime: 1790407971
+commit: 75f8f6d271afd980d4963eaada9f0b743c56944bd65cd54f6f7400bcd379e606
 url: https://src.opensuse.org/AI/mistral-vibe.git
 revision: factory
 

++++++ app_server_turn_timeouts.patch ++++++
From: Martin Pluskal <[email protected]>
Subject: give the turn tests room on a loaded build worker

The asyncio.wait_for() calls in these two modules allow one second for an
event the runtime sets almost immediately.  Under the parallel test run that
budget measures scheduling latency rather than a real bound, and two tests
(the background-title quiescence test here and the stale-turn-control test in
backend_contract) fail intermittently with TimeoutError.  Nothing in either
module asserts that a wait times out, so raise the budget; it stays below the
60 s pytest-timeout cap even when several waits stack up in one test.

Index: mistral-vibe-2.25.7/tests/app_server/backend_contract/test_turns.py
===================================================================
--- mistral-vibe-2.25.7.orig/tests/app_server/backend_contract/test_turns.py
+++ mistral-vibe-2.25.7/tests/app_server/backend_contract/test_turns.py
@@ -590,7 +590,7 @@ async def test_interrupt_terminates_an_a
 
     turn = asyncio.create_task(consume_turn())
     try:
-        await asyncio.wait_for(started.wait(), timeout=1)
+        await asyncio.wait_for(started.wait(), timeout=10)
         await backend_contract_session.interrupt()
         await turn
     finally:
@@ -715,7 +715,7 @@ async def test_steering_adds_a_public_us
 
     turn = asyncio.create_task(consume_turn())
     try:
-        await asyncio.wait_for(started.wait(), timeout=1)
+        await asyncio.wait_for(started.wait(), timeout=10)
         active_turn = backend_contract_session.state.latest_turn
         assert active_turn is not None
         await backend_contract_session.inject_user_context(
@@ -762,7 +762,7 @@ async def test_stale_turn_control_return
 
     turn = asyncio.create_task(consume_turn())
     try:
-        await asyncio.wait_for(started.wait(), timeout=1)
+        await asyncio.wait_for(started.wait(), timeout=10)
         with pytest.raises(AppServerResponseError) as exc_info:
             await backend_contract_connection.client.request(
                 "turn/steer",
@@ -802,10 +802,10 @@ async def test_reconnect_replays_turn_ou
 
     turn = asyncio.create_task(consume_turn())
     try:
-        await asyncio.wait_for(started.wait(), timeout=1)
+        await asyncio.wait_for(started.wait(), timeout=10)
         await backend_contract_connection.client.close()
         release.set()
-        events = await asyncio.wait_for(turn, timeout=1)
+        events = await asyncio.wait_for(turn, timeout=10)
     finally:
         release.set()
         if not turn.done():
Index: mistral-vibe-2.25.7/tests/app_server/test_turns.py
===================================================================
--- mistral-vibe-2.25.7.orig/tests/app_server/test_turns.py
+++ mistral-vibe-2.25.7/tests/app_server/test_turns.py
@@ -65,8 +65,8 @@ async def test_background_title_keeps_ru
     background_events = session.events()
 
     try:
-        during_turn = await asyncio.wait_for(_consume(turn_events), timeout=1)
-        await asyncio.wait_for(generation_started.wait(), timeout=1)
+        during_turn = await asyncio.wait_for(_consume(turn_events), timeout=10)
+        await asyncio.wait_for(generation_started.wait(), timeout=10)
 
         pending = [
             event
@@ -79,7 +79,7 @@ async def test_background_title_keeps_ru
         finish_generation.set()
         delivered: list[object] = []
         while True:
-            event = await asyncio.wait_for(background_events.__anext__(), 
timeout=1)
+            event = await asyncio.wait_for(background_events.__anext__(), 
timeout=10)
             delivered.append(event)
             if isinstance(event, SessionSnapshot) and event.state.is_quiescent 
is True:
                 break
@@ -127,8 +127,8 @@ async def test_retry_state_survives_unre
     turns = legacy_backend(server).session.turns
 
     try:
-        await asyncio.wait_for(retry_started.wait(), timeout=1)
-        retry_snapshot = await asyncio.wait_for(retry_snapshot_task, timeout=1)
+        await asyncio.wait_for(retry_started.wait(), timeout=10)
+        retry_snapshot = await asyncio.wait_for(retry_snapshot_task, 
timeout=10)
         legacy_retry = await _next_event(events, TurnRetrying)
         retrying = turns.retrying
         active_turn = turns.active_turn
@@ -185,7 +185,7 @@ async def test_interrupt_clears_retry_st
                 await retry_sink(RetryReason.from_http_status(503))
 
             future = asyncio.run_coroutine_threadsafe(report_retry(), loop)
-            future.result(timeout=1)
+            future.result(timeout=10)
 
         await asyncio.to_thread(emit_retry)
         retry_started.set()
@@ -203,8 +203,8 @@ async def test_interrupt_clears_retry_st
     turns = legacy_backend(server).session.turns
 
     try:
-        await asyncio.wait_for(retry_started.wait(), timeout=1)
-        retry_snapshot = await asyncio.wait_for(retry_snapshot_task, timeout=1)
+        await asyncio.wait_for(retry_started.wait(), timeout=10)
+        retry_snapshot = await asyncio.wait_for(retry_snapshot_task, 
timeout=10)
         await _next_event(events, TurnRetrying)
         assert turns.retrying is not None
         assert retry_snapshot.state.retrying == turns.retrying
@@ -251,7 +251,7 @@ async def test_retry_from_interrupted_tu
                         await self.on_retry(RetryReason.from_http_status(503))
 
                     future = asyncio.run_coroutine_threadsafe(report_retry(), 
loop)
-                    future.result(timeout=1)
+                    future.result(timeout=10)
                     loop.call_soon_threadsafe(late_retry_finished.set)
 
                 self.late_retry_task = asyncio.create_task(
@@ -280,23 +280,23 @@ async def test_retry_from_interrupted_tu
     second_consumer: asyncio.Task[list[object]] | None = None
 
     try:
-        await asyncio.wait_for(first_turn_started.wait(), timeout=1)
+        await asyncio.wait_for(first_turn_started.wait(), timeout=10)
         await session.interrupt()
-        await asyncio.wait_for(first_consumer, timeout=1)
+        await asyncio.wait_for(first_consumer, timeout=10)
         assert turns.retrying is None
 
         second_events = session.act("second")
         second_consumer = asyncio.create_task(_consume(second_events))
-        await asyncio.wait_for(second_turn_started.wait(), timeout=1)
+        await asyncio.wait_for(second_turn_started.wait(), timeout=10)
 
         release_late_retry.set()
-        await asyncio.wait_for(late_retry_finished.wait(), timeout=1)
+        await asyncio.wait_for(late_retry_finished.wait(), timeout=10)
 
         assert turns.retrying is None
         assert session.state.retrying is None
 
         finish_second_turn.set()
-        await asyncio.wait_for(second_consumer, timeout=1)
+        await asyncio.wait_for(second_consumer, timeout=10)
     finally:
         release_late_retry.set()
         finish_second_turn.set()

++++++ build.specials.obscpio ++++++

++++++ build.specials.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore      1970-01-01 01:00:00.000000000 +0100
+++ new/.gitignore      2026-09-26 09:32:51.000000000 +0200
@@ -0,0 +1,9 @@
+.assets
+_build.*
+*.obscpio
+*.obsinfo
+*.osc
+.pbuild
+_service:*
+mistral-vibe-*-build/
+.aider*

++++++ build_system_hatchling.patch ++++++
From: Martin Pluskal <[email protected]>
Subject: build the pure-Python distribution with hatchling

2.25.7 switched [build-system] to maturin so that the PyO3 extension
mistralai_vibe_local_harness._native is compiled from harness/core.  That crate
pulls deno_core/deno_ast and pins v8, whose build script either downloads a
prebuilt static library or fetches GN, ninja and clang from
chromium.googlesource.com -- neither is possible in an offline build, and
upstream publishes no sdist to fall back on.  Restore the 2.25.4 hatchling
configuration so the pure-Python vibe/ package is built; the Unified Harness is
optional at runtime (vibe/_experimental_harness.py defaults to the legacy
backend and raises ExperimentalHarnessUnavailableError when the distribution is
missing), so the CLI is fully functional without it, minus 
--experimental-harness.

Index: mistral-vibe-2.25.7/pyproject.toml
===================================================================
--- mistral-vibe-2.25.7.orig/pyproject.toml
+++ mistral-vibe-2.25.7/pyproject.toml
@@ -141,33 +141,24 @@ Issues = "https://github.com/mistralai/m
 Documentation = "https://github.com/mistralai/mistral-vibe#readme";
 
 [build-system]
-requires = ["maturin==1.14.1"]
-build-backend = "maturin_backend"
-backend-path = ["build_backend"]
+requires = ["hatchling==1.31.0", "hatch-vcs==0.5.0", "editables==0.6"]
+build-backend = "hatchling.build"
+
+[tool.hatch.metadata]
+allow-direct-references = true
 
 [[tool.uv.index]]
 default = true
 name = "pypi"
 url = "https://pypi.org/simple";
 
-[tool.maturin]
-manifest-path = ".native-build/harness-core/Cargo.toml"
-module-name = "mistralai_vibe_local_harness._native"
-python-source = "."
-python-packages = ["vibe", "mistralai_vibe_local_harness"]
-include = [
-    { path = "vibe/_bin/*", format = "wheel" },
-    # The runtime is staged during the build and ignored by Git. Include it
-    # explicitly so Maturin does not filter its Python sources out.
-    { path = "mistralai_vibe_local_harness/*", format = "wheel" },
-    { path = "mistralai_vibe_local_harness/**/*", format = "wheel" },
-]
-exclude = [
-    "**/__pycache__/**",
-    "**/*.pyc",
-    "vibe/cli-rust/**",
-]
-features = ["extension-module"]
+[tool.hatch.build.targets.wheel]
+# "packages", not the 2.25.4 "include": an include pattern is gitignore-style
+# and "vibe/" would also match harness/.../mistralai_vibe_local_harness/vibe.
+packages = ["vibe"]
+# vibe/cli-rust is the (unbuilt, separately licensed) Rust CLI source tree;
+# upstream's maturin config excludes it from the wheel too.
+exclude = ["vibe/cli-rust/**"]
 
 [project.scripts]
 vibe = "vibe.cli.launcher:main"

++++++ fingerprint_file_contents.patch ++++++
--- /var/tmp/diff_new_pack.km2hhE/_old  2026-09-28 10:45:50.291407984 +0200
+++ /var/tmp/diff_new_pack.km2hhE/_new  2026-09-28 10:45:50.306408613 +0200
@@ -9,12 +9,12 @@
 Contents are read with os.pread() so the caller's file position is untouched 
and
 the O_RDWR temp handle of the atomic-write path can still be fingerprinted.
 
-Index: mistral-vibe-2.25.0/vibe/core/config/fingerprint.py
+Index: mistral-vibe-2.25.7/vibe/core/config/fingerprint.py
 ===================================================================
---- mistral-vibe-2.25.0.orig/vibe/core/config/fingerprint.py
-+++ mistral-vibe-2.25.0/vibe/core/config/fingerprint.py
-@@ -27,10 +27,35 @@ def capture_stable_file(path: Path) -> I
-         raise ConcurrencyConflictError(expected_fp=before, actual_fp=after)
+--- mistral-vibe-2.25.7.orig/vibe/core/config/fingerprint.py
++++ mistral-vibe-2.25.7/vibe/core/config/fingerprint.py
+@@ -29,10 +29,35 @@ def open_fingerprinted_file(path: Path)
+         yield file, create_file_fingerprint(file)
  
  
 +_FINGERPRINT_CHUNK_SIZE = 1 << 16

++++++ fix_ui_tests.patch ++++++
--- /var/tmp/diff_new_pack.km2hhE/_old  2026-09-28 10:45:50.349410414 +0200
+++ /var/tmp/diff_new_pack.km2hhE/_new  2026-09-28 10:45:50.356410708 +0200
@@ -7,10 +7,10 @@
  tests/test_ui_rewind.py                           |    2 ++
  6 files changed, 20 insertions(+), 2 deletions(-)
 
-Index: mistral-vibe-2.25.1/tests/app_server/test_vibe_code.py
+Index: mistral-vibe-2.25.7/tests/app_server/test_vibe_code.py
 ===================================================================
---- mistral-vibe-2.25.1.orig/tests/app_server/test_vibe_code.py
-+++ mistral-vibe-2.25.1/tests/app_server/test_vibe_code.py
+--- mistral-vibe-2.25.7.orig/tests/app_server/test_vibe_code.py
++++ mistral-vibe-2.25.7/tests/app_server/test_vibe_code.py
 @@ -68,7 +68,7 @@ def test_app_server_import_does_not_requ
          capture_output=True,
          env=env,
@@ -20,10 +20,10 @@
      )
  
      assert result.returncode == 0, result.stderr
-Index: mistral-vibe-2.25.1/tests/cli/test_ui_config_and_model_picker.py
+Index: mistral-vibe-2.25.7/tests/cli/test_ui_config_and_model_picker.py
 ===================================================================
---- mistral-vibe-2.25.1.orig/tests/cli/test_ui_config_and_model_picker.py
-+++ mistral-vibe-2.25.1/tests/cli/test_ui_config_and_model_picker.py
+--- mistral-vibe-2.25.7.orig/tests/cli/test_ui_config_and_model_picker.py
++++ mistral-vibe-2.25.7/tests/cli/test_ui_config_and_model_picker.py
 @@ -1,5 +1,6 @@
  from __future__ import annotations
  
@@ -31,7 +31,7 @@
  from unittest.mock import AsyncMock, patch
  
  import pytest
-@@ -52,6 +53,15 @@ async def _open_model_picker(pilot, app)
+@@ -54,6 +55,15 @@ async def _open_model_picker(pilot, app)
      return picker
  
  
@@ -47,7 +47,7 @@
  # --- /model command ---
  
  
-@@ -181,7 +191,7 @@ async def test_model_picker_select_curre
+@@ -183,7 +193,7 @@ async def test_model_picker_select_curre
          await _open_model_picker(pilot, app)
  
          await pilot.press("enter")
@@ -56,10 +56,10 @@
  
          assert app.config.active_model.alias == "alpha"
          assert app._current_bottom_app == BottomApp.Input
-Index: mistral-vibe-2.25.1/tests/cli/test_ui_session_incremental_renderer.py
+Index: mistral-vibe-2.25.7/tests/cli/test_ui_session_incremental_renderer.py
 ===================================================================
---- mistral-vibe-2.25.1.orig/tests/cli/test_ui_session_incremental_renderer.py
-+++ mistral-vibe-2.25.1/tests/cli/test_ui_session_incremental_renderer.py
+--- mistral-vibe-2.25.7.orig/tests/cli/test_ui_session_incremental_renderer.py
++++ mistral-vibe-2.25.7/tests/cli/test_ui_session_incremental_renderer.py
 @@ -5,6 +5,8 @@ from pathlib import Path
  import time
  
@@ -69,10 +69,10 @@
  from textual.widgets import Button
  
  from tests.conftest import build_test_agent_loop
-Index: mistral-vibe-2.25.1/tests/cli/test_ui_skill_dispatch.py
+Index: mistral-vibe-2.25.7/tests/cli/test_ui_skill_dispatch.py
 ===================================================================
---- mistral-vibe-2.25.1.orig/tests/cli/test_ui_skill_dispatch.py
-+++ mistral-vibe-2.25.1/tests/cli/test_ui_skill_dispatch.py
+--- mistral-vibe-2.25.7.orig/tests/cli/test_ui_skill_dispatch.py
++++ mistral-vibe-2.25.7/tests/cli/test_ui_skill_dispatch.py
 @@ -8,6 +8,8 @@ from weakref import WeakKeyDictionary
  
  import pytest
@@ -82,27 +82,27 @@
  from tests.conftest import (
      build_test_agent_loop,
      build_test_vibe_app,
-Index: mistral-vibe-2.25.1/tests/cli/textual_ui/test_app_server_requests.py
+Index: mistral-vibe-2.25.7/tests/cli/textual_ui/test_app_server_requests.py
 ===================================================================
---- mistral-vibe-2.25.1.orig/tests/cli/textual_ui/test_app_server_requests.py
-+++ mistral-vibe-2.25.1/tests/cli/textual_ui/test_app_server_requests.py
-@@ -8,6 +8,8 @@ from unittest.mock import AsyncMock, Mag
- 
+--- mistral-vibe-2.25.7.orig/tests/cli/textual_ui/test_app_server_requests.py
++++ mistral-vibe-2.25.7/tests/cli/textual_ui/test_app_server_requests.py
+@@ -10,6 +10,8 @@ from unittest.mock import AsyncMock, Mag
  import pytest
+ from textual.worker import WorkerCancelled
  
 +pytestmark = pytest.mark.terminal
 +
  from tests.conftest import (
      build_test_agent_loop,
      build_test_vibe_app,
-Index: mistral-vibe-2.25.1/tests/test_ui_rewind.py
+Index: mistral-vibe-2.25.7/tests/test_ui_rewind.py
 ===================================================================
---- mistral-vibe-2.25.1.orig/tests/test_ui_rewind.py
-+++ mistral-vibe-2.25.1/tests/test_ui_rewind.py
-@@ -4,6 +4,8 @@ from contextlib import suppress
-
+--- mistral-vibe-2.25.7.orig/tests/test_ui_rewind.py
++++ mistral-vibe-2.25.7/tests/test_ui_rewind.py
+@@ -5,6 +5,8 @@ from contextlib import suppress
+ 
  import pytest
-
+ 
 +pytestmark = pytest.mark.terminal
 +
  from tests.conftest import build_test_agent_loop, build_test_vibe_app, 
wait_until

++++++ greeting_startup_race.patch ++++++
From: Martin Pluskal <[email protected]>
Subject: do not crash the post-ready worker when the chat is gone

_show_greeting_message() runs inside the non-exclusive worker started by
_start_post_ready_startup(), after an await on the account and identity
refreshes.  When the chat widget is not on the screen by the time that await
returns, query_one("#chat") raises NoMatches out of the worker and Textual
re-raises it at the end of run_test(), failing whichever UI test happened to
be running.  The greeting is cosmetic, so skip it; messages.py already guards
the same lookup this way.

Index: mistral-vibe-2.25.7/vibe/cli/textual_ui/app.py
===================================================================
--- mistral-vibe-2.25.7.orig/vibe/cli/textual_ui/app.py
+++ mistral-vibe-2.25.7/vibe/cli/textual_ui/app.py
@@ -22,6 +22,7 @@ from rich import print as rprint
 from textual.app import WINDOWS, App, ComposeResult
 from textual.binding import Binding, BindingType
 from textual.containers import Horizontal, VerticalGroup, VerticalScroll
+from textual.css.query import NoMatches
 from textual.dom import NoScreen
 from textual.driver import Driver
 from textual.events import AppBlur, AppFocus, MouseScrollDown, MouseScrollUp, 
MouseUp
@@ -6267,7 +6268,12 @@ class VibeApp(App):  # noqa: PLR0904
         if username is None:
             return
         greeting_message = GreetingMessage(username)
-        chat = self._chat_widget
+        try:
+            chat = self._chat_widget
+        except NoMatches:
+            # Nothing to mount into: this runs in the post-ready worker, which
+            # can still be waiting on the network when the chat goes away.
+            return
         # Mount after banner so it appears below banner and scrolls up with 
messages
         await chat.mount(greeting_message, after=self._banner)
         self._greeting_message = greeting_message

++++++ harness_importorskip.patch ++++++
--- /var/tmp/diff_new_pack.km2hhE/_old  2026-09-28 10:45:50.424413557 +0200
+++ /var/tmp/diff_new_pack.km2hhE/_new  2026-09-28 10:45:50.433413934 +0200
@@ -1,24 +1,99 @@
----
- tests/app_server/test_unified_harness_backend_adapter.py |    5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
+From: Martin Pluskal <[email protected]>
+Subject: skip the harness-only tests when the harness is absent
 
-Index: 
mistral-vibe-2.25.1/tests/app_server/test_unified_harness_backend_adapter.py
+mistralai-vibe-local-harness is built by the maturin backend this package
+does not run, so the distribution is not installed.  Guard the test modules
+that import it at module scope with pytest.importorskip, the way upstream
+already guards its other harness tests, so collection skips them instead of
+erroring.
+
+Index: 
mistral-vibe-2.25.7/tests/app_server/test_unified_harness_backend_adapter.py
 ===================================================================
---- 
mistral-vibe-2.25.1.orig/tests/app_server/test_unified_harness_backend_adapter.py
-+++ 
mistral-vibe-2.25.1/tests/app_server/test_unified_harness_backend_adapter.py
-@@ -14,10 +14,13 @@
+--- 
mistral-vibe-2.25.7.orig/tests/app_server/test_unified_harness_backend_adapter.py
++++ 
mistral-vibe-2.25.7/tests/app_server/test_unified_harness_backend_adapter.py
+@@ -17,6 +17,13 @@ from types import SimpleNamespace
  from typing import TYPE_CHECKING, Any, Literal, cast
  from unittest.mock import AsyncMock, Mock
  
--import mistralai_vibe_local_harness.session_protocol as 
harness_session_protocol
- import pytest
- import tomli_w
- 
-+# mistralai-vibe-local-harness is an optional extra: skip this module when
-+# it is missing instead of failing collection, like the other harness tests
-+harness_session_protocol = 
pytest.importorskip("mistralai_vibe_local_harness.session_protocol")
++import pytest
++import tomli_w
++
++# mistralai-vibe-local-harness is an optional extra openSUSE does not ship:
++# skip instead of failing collection, like upstream's own harness guards.
++pytest.importorskip("mistralai_vibe_local_harness")
 +
+ import mistralai_vibe_local_harness.session_protocol as 
harness_session_protocol
+ from mistralai_vibe_local_harness.vibe import (
+     DeferredTurnPreparationContext as HarnessDeferredTurnPreparationContext,
+@@ -25,8 +32,6 @@ from mistralai_vibe_local_harness.vibe i
+     DeferredTurnStartParams as HarnessDeferredTurnStartParams,
+     DeferredTurnStartResult as HarnessDeferredTurnStartResult,
+ )
+-import pytest
+-import tomli_w
+ 
  from tests.conftest import build_test_agent_loop, build_test_vibe_config
  from tests.mock.utils import mock_llm_chunk
- from tests.stubs.app_server import build_test_app_server
+Index: mistral-vibe-2.25.7/tests/app_server/test_provided_tools.py
+===================================================================
+--- mistral-vibe-2.25.7.orig/tests/app_server/test_provided_tools.py
++++ mistral-vibe-2.25.7/tests/app_server/test_provided_tools.py
+@@ -3,6 +3,12 @@ from __future__ import annotations
+ from collections.abc import Awaitable, Callable
+ from pathlib import Path
+ 
++import pytest
++
++# mistralai-vibe-local-harness is an optional extra openSUSE does not ship:
++# skip instead of failing collection, like upstream's own harness guards.
++pytest.importorskip("mistralai_vibe_local_harness")
++
+ from mistralai_vibe_local_harness.protocol import (
+     JsonObject,
+     JsonSchema,
+@@ -13,7 +19,6 @@ from mistralai_vibe_local_harness.protoc
+     RustToolFailedEvent,
+     RustToolSucceededEvent,
+ )
+-import pytest
+ 
+ from vibe.app_server._provided_tools import (
+     TODO_TOOL_NAME,
+Index: mistral-vibe-2.25.7/tests/app_server/test_unified_scratchpad.py
+===================================================================
+--- mistral-vibe-2.25.7.orig/tests/app_server/test_unified_scratchpad.py
++++ mistral-vibe-2.25.7/tests/app_server/test_unified_scratchpad.py
+@@ -433,6 +433,7 @@ async def test_notes_written_through_the
+ def test_the_scratchpad_lives_inside_the_harness_session_directory(
+     tmp_path: Path,
+ ) -> None:
++    pytest.importorskip("mistralai_vibe_local_harness")
+     from mistralai_vibe_local_harness.vibe._host import 
UnifiedHarnessSessionBackendHost
+ 
+     # Reaching for the private ``_session_root`` on purpose: the scratchpad 
shares
+Index: mistral-vibe-2.25.7/tests/app_server/test_unified_tool_projection.py
+===================================================================
+--- mistral-vibe-2.25.7.orig/tests/app_server/test_unified_tool_projection.py
++++ mistral-vibe-2.25.7/tests/app_server/test_unified_tool_projection.py
+@@ -4,6 +4,12 @@ import asyncio
+ from copy import deepcopy
+ from pathlib import Path
+ 
++import pytest
++
++# mistralai-vibe-local-harness is an optional extra openSUSE does not ship:
++# skip instead of failing collection, like upstream's own harness guards.
++pytest.importorskip("mistralai_vibe_local_harness")
++
+ from mistralai_vibe_local_harness.protocol import (
+     JsonObject,
+     RustEvent,
+@@ -11,7 +17,6 @@ from mistralai_vibe_local_harness.protoc
+     RustProvidedToolCallAction,
+     RustToolSucceededEvent,
+ )
+-import pytest
+ 
+ from vibe.app_server._provided_tools import VIBE_TOOL_GROUP, VibeProvidedTools
+ from vibe.app_server._unified_scratchpad import SCRATCHPAD_TOOL_NAME
 

++++++ harness_optional_import.patch ++++++
From: Martin Pluskal <[email protected]>
Subject: keep the Harness off the legacy import path

_provided_tools imports mistralai_vibe_local_harness.protocol at module scope,
so the module-scope import of it here pulled the Harness distribution in for
every app-server import -- including the legacy path, which must run without
it (the neighbouring imports below say so).  vibe_tool_groups() is only ever
called from build_unified_session_context(), so import it there.

Index: mistral-vibe-2.25.7/vibe/app_server/_runtime.py
===================================================================
--- mistral-vibe-2.25.7.orig/vibe/app_server/_runtime.py
+++ mistral-vibe-2.25.7/vibe/app_server/_runtime.py
@@ -29,7 +29,6 @@ from vibe.app_server._projection import
     project_skill_summaries,
     project_unified_agent_summaries,
 )
-from vibe.app_server._provided_tools import vibe_tool_groups
 from vibe.app_server._session_backend_port import SessionBackendHost
 from vibe.app_server._session_backend_services import SessionBackendServices
 from vibe.app_server._session_model import (
@@ -1331,6 +1330,7 @@ class HarnessProcess:
 
         # Imported here rather than at module scope: it depends on the Harness
         # package, which only exists under the experimental-harness extra.
+        from vibe.app_server._provided_tools import vibe_tool_groups
         from vibe.app_server._provider_credentials import 
ProviderCredentialService
         from vibe.app_server._unified_harness_backend_adapter import (
             CorrelationIdHolder,

++++++ mistral-vibe-2.25.4.tar.gz -> mistral-vibe-2.25.8.tar.gz ++++++
++++ 469987 lines of diff (skipped)

++++++ no_network.patch ++++++
--- /var/tmp/diff_new_pack.km2hhE/_old  2026-09-28 10:45:52.835514572 +0200
+++ /var/tmp/diff_new_pack.km2hhE/_new  2026-09-28 10:45:52.841514824 +0200
@@ -16,11 +16,11 @@
  tests/test_install_script.py                          |    3 +++
  15 files changed, 36 insertions(+)
 
-Index: mistral-vibe-2.25.0/pyproject.toml
+Index: mistral-vibe-2.25.7/pyproject.toml
 ===================================================================
---- mistral-vibe-2.25.0.orig/pyproject.toml
-+++ mistral-vibe-2.25.0/pyproject.toml
-@@ -272,6 +272,7 @@ addopts = "-p pytest_vibe -vvvv -q -n au
+--- mistral-vibe-2.25.7.orig/pyproject.toml
++++ mistral-vibe-2.25.7/pyproject.toml
+@@ -306,6 +306,7 @@ addopts = "-p pytest_vibe -vvvv -q -n au
  timeout = 10
  markers = [
      "unified_supported: backend contract behavior implemented by the Unified 
Harness",
@@ -28,10 +28,10 @@
  ]
  filterwarnings = [
      # (e2e) streaming mock server is started in a thread; and the cli is 
spawn in a fork
-Index: mistral-vibe-2.25.0/tests/acp/test_acp_entrypoint_smoke.py
+Index: mistral-vibe-2.25.7/tests/acp/test_acp_entrypoint_smoke.py
 ===================================================================
---- mistral-vibe-2.25.0.orig/tests/acp/test_acp_entrypoint_smoke.py
-+++ mistral-vibe-2.25.0/tests/acp/test_acp_entrypoint_smoke.py
+--- mistral-vibe-2.25.7.orig/tests/acp/test_acp_entrypoint_smoke.py
++++ mistral-vibe-2.25.7/tests/acp/test_acp_entrypoint_smoke.py
 @@ -29,6 +29,8 @@ BROWSER_AUTH_DESCRIPTION = (
      "Sign into Mistral Vibe through your Mistral AI Studio account."
  )
@@ -41,11 +41,11 @@
  
  class _AcpSmokeClient(Client):
      def on_connect(self, conn: Any) -> None:
-Index: mistral-vibe-2.25.0/tests/app_server/test_transport.py
+Index: mistral-vibe-2.25.7/tests/app_server/test_transport.py
 ===================================================================
---- mistral-vibe-2.25.0.orig/tests/app_server/test_transport.py
-+++ mistral-vibe-2.25.0/tests/app_server/test_transport.py
-@@ -240,6 +240,7 @@ async def test_stdio_transport_close_is_
+--- mistral-vibe-2.25.7.orig/tests/app_server/test_transport.py
++++ mistral-vibe-2.25.7/tests/app_server/test_transport.py
+@@ -281,6 +281,7 @@ async def test_stdio_transport_close_is_
      assert [json.loads(line) for line in writer.getvalue().splitlines()] == 
[{"id": 1}]
  
  
@@ -53,10 +53,10 @@
  @pytest.mark.asyncio
  async def test_stdio_server_uses_the_same_json_rpc_lifecycle() -> None:
      agent_loop = build_test_agent_loop()
-Index: mistral-vibe-2.25.0/tests/cli/test_audio_config_boundary.py
+Index: mistral-vibe-2.25.7/tests/cli/test_audio_config_boundary.py
 ===================================================================
---- mistral-vibe-2.25.0.orig/tests/cli/test_audio_config_boundary.py
-+++ mistral-vibe-2.25.0/tests/cli/test_audio_config_boundary.py
+--- mistral-vibe-2.25.7.orig/tests/cli/test_audio_config_boundary.py
++++ mistral-vibe-2.25.7/tests/cli/test_audio_config_boundary.py
 @@ -9,6 +9,7 @@ from tests.stubs.fake_voice_manager impo
  from vibe.cli.narrator_manager import NarratorState
  
@@ -81,10 +81,10 @@
  @pytest.mark.asyncio
  async def test_narrator_sync_observes_accepted_config() -> None:
      narrator = MagicMock()
-Index: mistral-vibe-2.25.0/tests/cli/test_log_level_command.py
+Index: mistral-vibe-2.25.7/tests/cli/test_log_level_command.py
 ===================================================================
---- mistral-vibe-2.25.0.orig/tests/cli/test_log_level_command.py
-+++ mistral-vibe-2.25.0/tests/cli/test_log_level_command.py
+--- mistral-vibe-2.25.7.orig/tests/cli/test_log_level_command.py
++++ mistral-vibe-2.25.7/tests/cli/test_log_level_command.py
 @@ -199,6 +199,7 @@ async def test_picker_session_cleared_sh
      assert get_session_override() is None
  
@@ -93,11 +93,11 @@
  @pytest.mark.asyncio
  async def test_picker_config_write_failure_surfaces_error(monkeypatch) -> 
None:
      # When the inline (idle) config write fails, the picker must surface an
-Index: mistral-vibe-2.25.0/tests/cli/test_ui_config_and_model_picker.py
+Index: mistral-vibe-2.25.7/tests/cli/test_ui_config_and_model_picker.py
 ===================================================================
---- mistral-vibe-2.25.0.orig/tests/cli/test_ui_config_and_model_picker.py
-+++ mistral-vibe-2.25.0/tests/cli/test_ui_config_and_model_picker.py
-@@ -151,6 +151,7 @@ async def test_model_picker_escape_does_
+--- mistral-vibe-2.25.7.orig/tests/cli/test_ui_config_and_model_picker.py
++++ mistral-vibe-2.25.7/tests/cli/test_ui_config_and_model_picker.py
+@@ -153,6 +153,7 @@ async def test_model_picker_escape_does_
              update_config.assert_not_awaited()
  
  
@@ -105,10 +105,10 @@
  @pytest.mark.asyncio
  async def test_model_picker_select_model() -> None:
      app = build_test_vibe_app(config=_make_config_with_models())
-Index: 
mistral-vibe-2.25.0/tests/cli/textual_ui/test_custom_tools_deprecation.py
+Index: 
mistral-vibe-2.25.7/tests/cli/textual_ui/test_custom_tools_deprecation.py
 ===================================================================
---- 
mistral-vibe-2.25.0.orig/tests/cli/textual_ui/test_custom_tools_deprecation.py
-+++ mistral-vibe-2.25.0/tests/cli/textual_ui/test_custom_tools_deprecation.py
+--- 
mistral-vibe-2.25.7.orig/tests/cli/textual_ui/test_custom_tools_deprecation.py
++++ mistral-vibe-2.25.7/tests/cli/textual_ui/test_custom_tools_deprecation.py
 @@ -21,6 +21,7 @@ async def _wait_for(predicate: Callable[
      pytest.fail("Condition not met within timeout")
  
@@ -125,11 +125,11 @@
  @pytest.mark.asyncio
  async def test_rebuilding_the_transcript_restores_the_custom_tools_warning(
      tmp_path: Path,
-Index: mistral-vibe-2.25.0/tests/conftest.py
+Index: mistral-vibe-2.25.7/tests/conftest.py
 ===================================================================
---- mistral-vibe-2.25.0.orig/tests/conftest.py
-+++ mistral-vibe-2.25.0/tests/conftest.py
-@@ -238,6 +238,17 @@ def _mock_api_key(monkeypatch: pytest.Mo
+--- mistral-vibe-2.25.7.orig/tests/conftest.py
++++ mistral-vibe-2.25.7/tests/conftest.py
+@@ -275,6 +275,17 @@ def _mock_api_key(monkeypatch: pytest.Mo
  
  
  @pytest.fixture(autouse=True)
@@ -147,22 +147,22 @@
  def _mock_platform(monkeypatch: pytest.MonkeyPatch) -> None:
      """Mock platform to be Linux with /bin/sh shell for consistent test 
behavior.
  
-Index: mistral-vibe-2.25.0/tests/e2e/test_cli_tui_fresh_install.py
+Index: mistral-vibe-2.25.7/tests/e2e/test_cli_tui_fresh_install.py
 ===================================================================
---- mistral-vibe-2.25.0.orig/tests/e2e/test_cli_tui_fresh_install.py
-+++ mistral-vibe-2.25.0/tests/e2e/test_cli_tui_fresh_install.py
-@@ -62,6 +62,7 @@ def _install_fresh_wheel(tmp_path: Path,
+--- mistral-vibe-2.25.7.orig/tests/e2e/test_cli_tui_fresh_install.py
++++ mistral-vibe-2.25.7/tests/e2e/test_cli_tui_fresh_install.py
+@@ -81,6 +81,7 @@ def _install_fresh_wheel(tmp_path: Path,
      return _venv_executable(venv_path, "vibe")
  
  
 [email protected]
- @pytest.mark.timeout(90)
+ @pytest.mark.timeout(900)
  def test_fresh_wheel_install_can_spawn_cli_and_complete_happy_path(
      streaming_mock_server: StreamingMockServer,
-Index: mistral-vibe-2.25.0/tests/e2e/test_cli_tui_hooks.py
+Index: mistral-vibe-2.25.7/tests/e2e/test_cli_tui_hooks.py
 ===================================================================
---- mistral-vibe-2.25.0.orig/tests/e2e/test_cli_tui_hooks.py
-+++ mistral-vibe-2.25.0/tests/e2e/test_cli_tui_hooks.py
+--- mistral-vibe-2.25.7.orig/tests/e2e/test_cli_tui_hooks.py
++++ mistral-vibe-2.25.7/tests/e2e/test_cli_tui_hooks.py
 @@ -18,6 +18,8 @@ from tests.e2e.common import (
  )
  from tests.e2e.mock_server import StreamingMockServer
@@ -172,10 +172,10 @@
  
  def _setup_recording_hook(vibe_home: Path, invocation_path: Path) -> None:
      script = vibe_home / "_record_hook.py"
-Index: mistral-vibe-2.25.0/tests/e2e/test_cli_tui_onboarding.py
+Index: mistral-vibe-2.25.7/tests/e2e/test_cli_tui_onboarding.py
 ===================================================================
---- mistral-vibe-2.25.0.orig/tests/e2e/test_cli_tui_onboarding.py
-+++ mistral-vibe-2.25.0/tests/e2e/test_cli_tui_onboarding.py
+--- mistral-vibe-2.25.7.orig/tests/e2e/test_cli_tui_onboarding.py
++++ mistral-vibe-2.25.7/tests/e2e/test_cli_tui_onboarding.py
 @@ -7,6 +7,8 @@ import pytest
  
  from tests.e2e.common import SpawnedVibeProcessFixture, ansi_tolerant_pattern
@@ -185,10 +185,10 @@
  
  @pytest.mark.timeout(15)
  def test_spawn_cli_shows_onboarding_when_api_key_missing(
-Index: mistral-vibe-2.25.0/tests/e2e/test_cli_tui_session_exit.py
+Index: mistral-vibe-2.25.7/tests/e2e/test_cli_tui_session_exit.py
 ===================================================================
---- mistral-vibe-2.25.0.orig/tests/e2e/test_cli_tui_session_exit.py
-+++ mistral-vibe-2.25.0/tests/e2e/test_cli_tui_session_exit.py
+--- mistral-vibe-2.25.7.orig/tests/e2e/test_cli_tui_session_exit.py
++++ mistral-vibe-2.25.7/tests/e2e/test_cli_tui_session_exit.py
 @@ -24,6 +24,8 @@ from tests.e2e.common import (
  from tests.e2e.mock_server import StreamingMockServer
  from vibe.utils.io import read_safe
@@ -198,10 +198,10 @@
  
  def _usage_by_run_factory(
      request_index: int, _payload: object
-Index: mistral-vibe-2.25.0/tests/e2e/test_cli_tui_streaming.py
+Index: mistral-vibe-2.25.7/tests/e2e/test_cli_tui_streaming.py
 ===================================================================
---- mistral-vibe-2.25.0.orig/tests/e2e/test_cli_tui_streaming.py
-+++ mistral-vibe-2.25.0/tests/e2e/test_cli_tui_streaming.py
+--- mistral-vibe-2.25.7.orig/tests/e2e/test_cli_tui_streaming.py
++++ mistral-vibe-2.25.7/tests/e2e/test_cli_tui_streaming.py
 @@ -14,6 +14,8 @@ from tests.e2e.common import (
  )
  from tests.e2e.mock_server import StreamingMockServer
@@ -211,10 +211,10 @@
  
  @pytest.mark.timeout(15)
  def test_spawn_cli_to_send_and_receive_message(
-Index: mistral-vibe-2.25.0/tests/e2e/test_cli_tui_tool_approval.py
+Index: mistral-vibe-2.25.7/tests/e2e/test_cli_tui_tool_approval.py
 ===================================================================
---- mistral-vibe-2.25.0.orig/tests/e2e/test_cli_tui_tool_approval.py
-+++ mistral-vibe-2.25.0/tests/e2e/test_cli_tui_tool_approval.py
+--- mistral-vibe-2.25.7.orig/tests/e2e/test_cli_tui_tool_approval.py
++++ mistral-vibe-2.25.7/tests/e2e/test_cli_tui_tool_approval.py
 @@ -14,6 +14,8 @@ from tests.e2e.common import (
  )
  from tests.e2e.mock_server import ChatCompletionsRequestPayload, 
StreamingMockServer
@@ -224,10 +224,10 @@
  PREDICTABLE_OUTPUT = "__E2E_BASH_OK__"
  TOOL_ARGUMENTS = f'{{"command":"printf \\"{PREDICTABLE_OUTPUT}\\\\n\\""}}'
  
-Index: mistral-vibe-2.25.0/tests/test_install_script.py
+Index: mistral-vibe-2.25.7/tests/test_install_script.py
 ===================================================================
---- mistral-vibe-2.25.0.orig/tests/test_install_script.py
-+++ mistral-vibe-2.25.0/tests/test_install_script.py
+--- mistral-vibe-2.25.7.orig/tests/test_install_script.py
++++ mistral-vibe-2.25.7/tests/test_install_script.py
 @@ -7,6 +7,8 @@ import stat
  import subprocess
  from textwrap import dedent

++++++ no_terminal.patch ++++++
--- /var/tmp/diff_new_pack.km2hhE/_old  2026-09-28 10:45:52.869515997 +0200
+++ /var/tmp/diff_new_pack.km2hhE/_new  2026-09-28 10:45:52.873516165 +0200
@@ -1,31 +1,8 @@
-# PATCH-FIX-OPENSUSE no_terminal.patch [email protected]
-# mark tests requiring a terminal or PTY so they are skipped in OBS builds
----
- pyproject.toml                                                 |    1 +
- tests/cli/test_switching_mode.py                               |    2 ++
- tests/cli/test_ui_clipboard_notifications.py                   |    2 ++
- tests/cli/test_ui_config_and_model_picker.py                   |    3 +++
- tests/cli/test_ui_config_screen.py                             |    3 +++
- tests/cli/test_ui_exit_command.py                              |    2 ++
- tests/cli/test_ui_theme_picker.py                              |    2 ++
- tests/cli/test_whoami_command.py                               |    2 ++
- tests/cli/test_word_selection.py                               |    2 ++
- tests/cli/textual_ui/test_chat_input_word_drag.py              |    2 ++
- tests/cli/textual_ui/test_message_queue_ui.py                  |    2 ++
- tests/e2e/agent_loop_characterization/test_resume.py           |    2 ++
- tests/e2e/agent_loop_characterization/test_subagents.py        |    2 ++
- tests/e2e/agent_loop_characterization/test_tool_execution.py   |    2 ++
- tests/e2e/agent_loop_characterization/test_tool_permissions.py |    2 ++
- tests/e2e/agent_loop_characterization/test_user_interaction.py |    2 ++
- tests/onboarding/test_ui_onboarding.py                         |    2 ++
- tests/tools/test_ui_bash_execution.py                          |    2 ++
- tests/vscode_extension_promo/test_ui_vscode_extension_promo.py |    2 ++
- 19 files changed, 39 insertions(+)
-Index: mistral-vibe-2.25.1/pyproject.toml
-===================================================================
---- mistral-vibe-2.25.1.orig/pyproject.toml
-+++ mistral-vibe-2.25.1/pyproject.toml
-@@ -273,6 +273,7 @@ timeout = 10
+Index: mistral-vibe-2.25.8/pyproject.toml
+===================================================================
+--- mistral-vibe-2.25.8.orig/pyproject.toml
++++ mistral-vibe-2.25.8/pyproject.toml
+@@ -307,6 +307,7 @@
  markers = [
      "unified_supported: backend contract behavior implemented by the Unified 
Harness",
      "network: tests that require network-capable execution environment",
@@ -33,11 +10,11 @@
  ]
  filterwarnings = [
      # (e2e) streaming mock server is started in a thread; and the cli is 
spawn in a fork
-Index: mistral-vibe-2.25.1/tests/cli/test_switching_mode.py
+Index: mistral-vibe-2.25.8/tests/cli/test_switching_mode.py
 ===================================================================
---- mistral-vibe-2.25.1.orig/tests/cli/test_switching_mode.py
-+++ mistral-vibe-2.25.1/tests/cli/test_switching_mode.py
-@@ -5,6 +5,8 @@ from unittest.mock import patch
+--- mistral-vibe-2.25.8.orig/tests/cli/test_switching_mode.py
++++ mistral-vibe-2.25.8/tests/cli/test_switching_mode.py
+@@ -5,6 +5,8 @@
  
  import pytest
  
@@ -46,11 +23,11 @@
  from tests.conftest import build_test_agent_loop, build_test_vibe_app
  from tests.mock.utils import mock_llm_chunk
  from tests.stubs.fake_backend import FakeBackend
-Index: mistral-vibe-2.25.1/tests/cli/test_ui_clipboard_notifications.py
+Index: mistral-vibe-2.25.8/tests/cli/test_ui_clipboard_notifications.py
 ===================================================================
---- mistral-vibe-2.25.1.orig/tests/cli/test_ui_clipboard_notifications.py
-+++ mistral-vibe-2.25.1/tests/cli/test_ui_clipboard_notifications.py
-@@ -3,6 +3,8 @@ from __future__ import annotations
+--- mistral-vibe-2.25.8.orig/tests/cli/test_ui_clipboard_notifications.py
++++ mistral-vibe-2.25.8/tests/cli/test_ui_clipboard_notifications.py
+@@ -3,6 +3,8 @@
  from unittest.mock import patch
  
  import pytest
@@ -59,11 +36,11 @@
  from textual.selection import Selection
  from textual.widget import Widget
  
-Index: mistral-vibe-2.25.1/tests/cli/test_ui_config_and_model_picker.py
+Index: mistral-vibe-2.25.8/tests/cli/test_ui_config_and_model_picker.py
 ===================================================================
---- mistral-vibe-2.25.1.orig/tests/cli/test_ui_config_and_model_picker.py
-+++ mistral-vibe-2.25.1/tests/cli/test_ui_config_and_model_picker.py
-@@ -3,6 +3,9 @@ from __future__ import annotations
+--- mistral-vibe-2.25.8.orig/tests/cli/test_ui_config_and_model_picker.py
++++ mistral-vibe-2.25.8/tests/cli/test_ui_config_and_model_picker.py
+@@ -3,6 +3,9 @@
  from unittest.mock import AsyncMock, patch
  
  import pytest
@@ -73,11 +50,11 @@
  from textual.widgets import OptionList
  
  from tests.conftest import build_test_vibe_app, build_test_vibe_config, 
wait_until
-Index: mistral-vibe-2.25.1/tests/cli/test_ui_config_screen.py
+Index: mistral-vibe-2.25.8/tests/cli/test_ui_config_screen.py
 ===================================================================
---- mistral-vibe-2.25.1.orig/tests/cli/test_ui_config_screen.py
-+++ mistral-vibe-2.25.1/tests/cli/test_ui_config_screen.py
-@@ -4,6 +4,9 @@ from pathlib import Path
+--- mistral-vibe-2.25.8.orig/tests/cli/test_ui_config_screen.py
++++ mistral-vibe-2.25.8/tests/cli/test_ui_config_screen.py
+@@ -4,6 +4,9 @@
  import tomllib
  
  import pytest
@@ -87,11 +64,11 @@
  from textual.pilot import Pilot
  import tomli_w
  
-Index: mistral-vibe-2.25.1/tests/cli/test_ui_exit_command.py
+Index: mistral-vibe-2.25.8/tests/cli/test_ui_exit_command.py
 ===================================================================
---- mistral-vibe-2.25.1.orig/tests/cli/test_ui_exit_command.py
-+++ mistral-vibe-2.25.1/tests/cli/test_ui_exit_command.py
-@@ -4,6 +4,8 @@ from typing import Any
+--- mistral-vibe-2.25.8.orig/tests/cli/test_ui_exit_command.py
++++ mistral-vibe-2.25.8/tests/cli/test_ui_exit_command.py
+@@ -4,6 +4,8 @@
  
  import pytest
  
@@ -100,11 +77,11 @@
  from tests.conftest import build_test_vibe_app
  from vibe.cli.textual_ui.widgets.chat_input.container import 
ChatInputContainer
  from vibe.cli.textual_ui.widgets.messages import SlashCommandMessage, 
UserMessage
-Index: mistral-vibe-2.25.1/tests/cli/test_ui_theme_picker.py
+Index: mistral-vibe-2.25.8/tests/cli/test_ui_theme_picker.py
 ===================================================================
---- mistral-vibe-2.25.1.orig/tests/cli/test_ui_theme_picker.py
-+++ mistral-vibe-2.25.1/tests/cli/test_ui_theme_picker.py
-@@ -7,6 +7,8 @@ from unittest.mock import AsyncMock, Moc
+--- mistral-vibe-2.25.8.orig/tests/cli/test_ui_theme_picker.py
++++ mistral-vibe-2.25.8/tests/cli/test_ui_theme_picker.py
+@@ -5,6 +5,8 @@
  
  import pytest
  
@@ -113,11 +90,11 @@
  from tests.conftest import build_test_vibe_app, build_test_vibe_config
  from vibe.cli.textual_ui.app import BottomApp
  from vibe.cli.textual_ui.widgets.theme_picker import ThemePickerApp
-Index: mistral-vibe-2.25.1/tests/cli/test_whoami_command.py
+Index: mistral-vibe-2.25.8/tests/cli/test_whoami_command.py
 ===================================================================
---- mistral-vibe-2.25.1.orig/tests/cli/test_whoami_command.py
-+++ mistral-vibe-2.25.1/tests/cli/test_whoami_command.py
-@@ -4,6 +4,8 @@ import asyncio
+--- mistral-vibe-2.25.8.orig/tests/cli/test_whoami_command.py
++++ mistral-vibe-2.25.8/tests/cli/test_whoami_command.py
+@@ -4,6 +4,8 @@
  
  import pytest
  
@@ -126,11 +103,11 @@
  from tests.conftest import build_test_vibe_app
  from tests.stubs.fake_account_gateway import FakeAccountGateway
  from tests.stubs.fake_identity_gateway import FakeIdentityGateway
-Index: mistral-vibe-2.25.1/tests/cli/test_word_selection.py
+Index: mistral-vibe-2.25.8/tests/cli/test_word_selection.py
 ===================================================================
---- mistral-vibe-2.25.1.orig/tests/cli/test_word_selection.py
-+++ mistral-vibe-2.25.1/tests/cli/test_word_selection.py
-@@ -3,6 +3,8 @@ from __future__ import annotations
+--- mistral-vibe-2.25.8.orig/tests/cli/test_word_selection.py
++++ mistral-vibe-2.25.8/tests/cli/test_word_selection.py
+@@ -3,6 +3,8 @@
  from typing import Any, ClassVar, cast
  
  import pytest
@@ -139,10 +116,10 @@
  from textual import events
  from textual.geometry import Offset, Region
  from textual.screen import Screen
-Index: mistral-vibe-2.25.1/tests/cli/textual_ui/test_chat_input_word_drag.py
+Index: mistral-vibe-2.25.8/tests/cli/textual_ui/test_chat_input_word_drag.py
 ===================================================================
---- mistral-vibe-2.25.1.orig/tests/cli/textual_ui/test_chat_input_word_drag.py
-+++ mistral-vibe-2.25.1/tests/cli/textual_ui/test_chat_input_word_drag.py
+--- mistral-vibe-2.25.8.orig/tests/cli/textual_ui/test_chat_input_word_drag.py
++++ mistral-vibe-2.25.8/tests/cli/textual_ui/test_chat_input_word_drag.py
 @@ -1,6 +1,8 @@
  from __future__ import annotations
  
@@ -152,24 +129,24 @@
  from textual import events
  from textual.widgets.text_area import Selection
  
-Index: mistral-vibe-2.25.1/tests/cli/textual_ui/test_message_queue_ui.py
+Index: mistral-vibe-2.25.8/tests/cli/textual_ui/test_message_queue_ui.py
 ===================================================================
---- mistral-vibe-2.25.1.orig/tests/cli/textual_ui/test_message_queue_ui.py
-+++ mistral-vibe-2.25.1/tests/cli/textual_ui/test_message_queue_ui.py
-@@ -4,6 +4,8 @@ from collections.abc import Iterator
-
+--- mistral-vibe-2.25.8.orig/tests/cli/textual_ui/test_message_queue_ui.py
++++ mistral-vibe-2.25.8/tests/cli/textual_ui/test_message_queue_ui.py
+@@ -5,6 +5,8 @@
+ 
  import pytest
-
+ 
 +pytestmark = pytest.mark.terminal
 +
  from tests.conftest import (
      build_test_agent_loop,
      build_test_vibe_app,
- Index: 
mistral-vibe-2.25.1/tests/e2e/agent_loop_characterization/test_resume.py
+Index: mistral-vibe-2.25.8/tests/e2e/agent_loop_characterization/test_resume.py
 ===================================================================
---- 
mistral-vibe-2.25.1.orig/tests/e2e/agent_loop_characterization/test_resume.py
-+++ mistral-vibe-2.25.1/tests/e2e/agent_loop_characterization/test_resume.py
-@@ -8,6 +8,8 @@ import time
+--- 
mistral-vibe-2.25.8.orig/tests/e2e/agent_loop_characterization/test_resume.py
++++ mistral-vibe-2.25.8/tests/e2e/agent_loop_characterization/test_resume.py
+@@ -8,6 +8,8 @@
  import pexpect
  import pytest
  
@@ -178,11 +155,11 @@
  from tests.e2e.agent_loop_characterization.support import (
      assert_assistant_tool_call_present,
      assert_message_content_present,
-Index: 
mistral-vibe-2.25.1/tests/e2e/agent_loop_characterization/test_subagents.py
+Index: 
mistral-vibe-2.25.8/tests/e2e/agent_loop_characterization/test_subagents.py
 ===================================================================
---- 
mistral-vibe-2.25.1.orig/tests/e2e/agent_loop_characterization/test_subagents.py
-+++ mistral-vibe-2.25.1/tests/e2e/agent_loop_characterization/test_subagents.py
-@@ -5,6 +5,8 @@ from pathlib import Path
+--- 
mistral-vibe-2.25.8.orig/tests/e2e/agent_loop_characterization/test_subagents.py
++++ mistral-vibe-2.25.8/tests/e2e/agent_loop_characterization/test_subagents.py
+@@ -5,6 +5,8 @@
  import pexpect
  import pytest
  
@@ -191,11 +168,11 @@
  from tests.e2e.agent_loop_characterization.support import (
      assert_message_content_present,
      assert_tool_result_contains,
-Index: 
mistral-vibe-2.25.1/tests/e2e/agent_loop_characterization/test_tool_execution.py
+Index: 
mistral-vibe-2.25.8/tests/e2e/agent_loop_characterization/test_tool_execution.py
 ===================================================================
---- 
mistral-vibe-2.25.1.orig/tests/e2e/agent_loop_characterization/test_tool_execution.py
-+++ 
mistral-vibe-2.25.1/tests/e2e/agent_loop_characterization/test_tool_execution.py
-@@ -6,6 +6,8 @@ from pathlib import Path
+--- 
mistral-vibe-2.25.8.orig/tests/e2e/agent_loop_characterization/test_tool_execution.py
++++ 
mistral-vibe-2.25.8/tests/e2e/agent_loop_characterization/test_tool_execution.py
+@@ -6,6 +6,8 @@
  import pexpect
  import pytest
  
@@ -204,11 +181,11 @@
  from tests.e2e.agent_loop_characterization.support import (
      answer_approval,
      assert_assistant_tool_call_present,
-Index: 
mistral-vibe-2.25.1/tests/e2e/agent_loop_characterization/test_tool_permissions.py
+Index: 
mistral-vibe-2.25.8/tests/e2e/agent_loop_characterization/test_tool_permissions.py
 ===================================================================
---- 
mistral-vibe-2.25.1.orig/tests/e2e/agent_loop_characterization/test_tool_permissions.py
-+++ 
mistral-vibe-2.25.1/tests/e2e/agent_loop_characterization/test_tool_permissions.py
-@@ -6,6 +6,8 @@ from pathlib import Path
+--- 
mistral-vibe-2.25.8.orig/tests/e2e/agent_loop_characterization/test_tool_permissions.py
++++ 
mistral-vibe-2.25.8/tests/e2e/agent_loop_characterization/test_tool_permissions.py
+@@ -6,6 +6,8 @@
  import pexpect
  import pytest
  
@@ -217,11 +194,11 @@
  from tests.e2e.agent_loop_characterization.support import (
      answer_approval,
      assert_tool_result_contains,
-Index: 
mistral-vibe-2.25.1/tests/e2e/agent_loop_characterization/test_user_interaction.py
+Index: 
mistral-vibe-2.25.8/tests/e2e/agent_loop_characterization/test_user_interaction.py
 ===================================================================
---- 
mistral-vibe-2.25.1.orig/tests/e2e/agent_loop_characterization/test_user_interaction.py
-+++ 
mistral-vibe-2.25.1/tests/e2e/agent_loop_characterization/test_user_interaction.py
-@@ -7,6 +7,8 @@ import time
+--- 
mistral-vibe-2.25.8.orig/tests/e2e/agent_loop_characterization/test_user_interaction.py
++++ 
mistral-vibe-2.25.8/tests/e2e/agent_loop_characterization/test_user_interaction.py
+@@ -7,6 +7,8 @@
  import pexpect
  import pytest
  
@@ -230,11 +207,11 @@
  from tests.e2e.agent_loop_characterization.support import (
      APPROVAL_INPUT_GRACE_PERIOD_S,
      assert_tool_result_contains,
-Index: mistral-vibe-2.25.1/tests/onboarding/test_ui_onboarding.py
+Index: mistral-vibe-2.25.8/tests/onboarding/test_ui_onboarding.py
 ===================================================================
---- mistral-vibe-2.25.1.orig/tests/onboarding/test_ui_onboarding.py
-+++ mistral-vibe-2.25.1/tests/onboarding/test_ui_onboarding.py
-@@ -10,6 +10,8 @@ from unittest.mock import MagicMock, pat
+--- mistral-vibe-2.25.8.orig/tests/onboarding/test_ui_onboarding.py
++++ mistral-vibe-2.25.8/tests/onboarding/test_ui_onboarding.py
+@@ -10,6 +10,8 @@
  import keyring
  from keyring.errors import KeyringError
  import pytest
@@ -243,11 +220,11 @@
  from textual.content import Content
  from textual.events import Resize
  from textual.geometry import Size
-Index: mistral-vibe-2.25.1/tests/tools/test_ui_bash_execution.py
+Index: mistral-vibe-2.25.8/tests/tools/test_ui_bash_execution.py
 ===================================================================
---- mistral-vibe-2.25.1.orig/tests/tools/test_ui_bash_execution.py
-+++ mistral-vibe-2.25.1/tests/tools/test_ui_bash_execution.py
-@@ -5,6 +5,8 @@ import time
+--- mistral-vibe-2.25.8.orig/tests/tools/test_ui_bash_execution.py
++++ mistral-vibe-2.25.8/tests/tools/test_ui_bash_execution.py
+@@ -5,6 +5,8 @@
  from pydantic import JsonValue
  import pytest
  
@@ -256,11 +233,11 @@
  from tests.conftest import build_test_agent_loop, build_test_vibe_app
  from tests.mock.utils import mock_llm_chunk
  from tests.stubs.fake_backend import FakeBackend
-Index: 
mistral-vibe-2.25.1/tests/vscode_extension_promo/test_ui_vscode_extension_promo.py
+Index: 
mistral-vibe-2.25.8/tests/vscode_extension_promo/test_ui_vscode_extension_promo.py
 ===================================================================
---- 
mistral-vibe-2.25.1.orig/tests/vscode_extension_promo/test_ui_vscode_extension_promo.py
-+++ 
mistral-vibe-2.25.1/tests/vscode_extension_promo/test_ui_vscode_extension_promo.py
-@@ -8,6 +8,8 @@ from unittest.mock import patch
+--- 
mistral-vibe-2.25.8.orig/tests/vscode_extension_promo/test_ui_vscode_extension_promo.py
++++ 
mistral-vibe-2.25.8/tests/vscode_extension_promo/test_ui_vscode_extension_promo.py
+@@ -8,6 +8,8 @@
  
  import pytest
  

++++++ obs-test-synchronization.patch ++++++
--- /var/tmp/diff_new_pack.km2hhE/_old  2026-09-28 10:45:52.892516961 +0200
+++ /var/tmp/diff_new_pack.km2hhE/_new  2026-09-28 10:45:52.896517128 +0200
@@ -1,7 +1,7 @@
-Index: mistral-vibe-2.25.0/tests/cli/test_connector_auth_app.py
+Index: mistral-vibe-2.25.7/tests/cli/test_connector_auth_app.py
 ===================================================================
---- mistral-vibe-2.25.0.orig/tests/cli/test_connector_auth_app.py
-+++ mistral-vibe-2.25.0/tests/cli/test_connector_auth_app.py
+--- mistral-vibe-2.25.7.orig/tests/cli/test_connector_auth_app.py
++++ mistral-vibe-2.25.7/tests/cli/test_connector_auth_app.py
 @@ -253,8 +253,8 @@ class TestCloseAndRefresh:
      async def test_action_refresh_dispatches_worker(self) -> None:
          app = _make_app()
@@ -13,11 +13,11 @@
  
          app.run_worker = MagicMock(side_effect=close_worker)
          app.query_one = MagicMock()
-Index: mistral-vibe-2.25.0/tests/cli/test_mcp_app.py
+Index: mistral-vibe-2.25.7/tests/cli/test_mcp_app.py
 ===================================================================
---- mistral-vibe-2.25.0.orig/tests/cli/test_mcp_app.py
-+++ mistral-vibe-2.25.0/tests/cli/test_mcp_app.py
-@@ -433,8 +433,8 @@ def test_refresh_index_replaces_state_fr
+--- mistral-vibe-2.25.7.orig/tests/cli/test_mcp_app.py
++++ mistral-vibe-2.25.7/tests/cli/test_mcp_app.py
+@@ -466,8 +466,8 @@ def test_refresh_index_replaces_state_fr
  def test_start_refresh_dispatches_one_worker() -> None:
      app = MCPApp(_state(), 
refresh_callback=AsyncMock(return_value="Refreshed"))
  
@@ -28,10 +28,10 @@
  
      app.run_worker = MagicMock(side_effect=close_worker)
  
-Index: mistral-vibe-2.25.0/tests/update_notifier/test_ui_update_notification.py
+Index: mistral-vibe-2.25.7/tests/update_notifier/test_ui_update_notification.py
 ===================================================================
---- 
mistral-vibe-2.25.0.orig/tests/update_notifier/test_ui_update_notification.py
-+++ mistral-vibe-2.25.0/tests/update_notifier/test_ui_update_notification.py
+--- 
mistral-vibe-2.25.7.orig/tests/update_notifier/test_ui_update_notification.py
++++ mistral-vibe-2.25.7/tests/update_notifier/test_ui_update_notification.py
 @@ -28,6 +28,15 @@ from vibe.core.config import VibeConfigS
  TEST_CURRENT_VERSION = "0.1.0"
  
@@ -73,23 +73,14 @@
          await _assert_no_notifications(app, pilot, timeout=0.3)
      assert notifier.fetch_update_calls == 1
  
-Index: mistral-vibe-2.25.1/tests/autocompletion/test_ui_chat_autocompletion.py
+Index: mistral-vibe-2.25.7/tests/autocompletion/test_ui_chat_autocompletion.py
 ===================================================================
---- 
mistral-vibe-2.25.1.orig/tests/autocompletion/test_ui_chat_autocompletion.py
-+++ mistral-vibe-2.25.1/tests/autocompletion/test_ui_chat_autocompletion.py
-@@ -2,6 +2,7 @@
- 
- from pathlib import Path
- 
-+import asyncio
- import pytest
- from textual.widgets import Markdown
- 
-@@ -12,6 +13,14 @@
-     _CompletionRow,
- )
+--- 
mistral-vibe-2.25.7.orig/tests/autocompletion/test_ui_chat_autocompletion.py
++++ mistral-vibe-2.25.7/tests/autocompletion/test_ui_chat_autocompletion.py
+@@ -18,6 +18,15 @@ from vibe.cli.textual_ui.widgets.chat_in
  from vibe.cli.textual_ui.widgets.chat_input.container import 
ChatInputContainer
-+
+ 
+ 
 +async def _wait_until(pilot, predicate, timeout: float = 6.0) -> bool:
 +    deadline = asyncio.get_running_loop().time() + timeout
 +    while asyncio.get_running_loop().time() < deadline:
@@ -97,10 +88,12 @@
 +            return True
 +        await pilot.pause(0.05)
 +    return predicate()
- 
- 
++
++
  @pytest.mark.asyncio
-@@ -183,6 +192,21 @@
+ async def test_popup_appears_with_matching_suggestions(vibe_app: VibeApp) -> 
None:
+     async with vibe_app.run_test() as pilot:
+@@ -187,6 +196,21 @@ async def test_path_completion_popup_sho
  
          await pilot.press(*"@src/core/extra/")
  
@@ -122,20 +115,8 @@
          popup_content = popup.content_text
          assert "src/core/extra/extra_file_1.py" in popup_content
          assert "src/core/extra/extra_file_10.py" in popup_content
-@@ -225,9 +249,8 @@
- 
-         await pilot.press(*"Print @REA")
-         await pilot.press("tab")
--        await pilot.pause(0.2)
--
--        assert chat_input.value == "Print @README.md "
-+
-+        assert await _wait_until(pilot, lambda: chat_input.value == "Print 
@README.md ")
-         assert popup.styles.display == "none"
- 
- 
-@@ -242,7 +265,7 @@
-         await pilot.press(*"Print @src/m")
+@@ -287,7 +311,7 @@ async def test_pressing_enter_writes_sel
+         await wait_for_path_completions(pilot)
          await pilot.press("enter")
  
 -        assert chat_input.value == "Print @src/main.py "
@@ -143,7 +124,7 @@
          assert popup.styles.display == "none"
  
  
-@@ -317,7 +340,7 @@
+@@ -363,7 +387,7 @@ async def test_does_not_trigger_completi
          await pilot.press(*message_to_fill_history)
          await pilot.press("enter")
          await pilot.press("up", "up")
@@ -152,9 +133,12 @@
          await pilot.pause(0.2)
          # ensure popup is hidden - user was navigating history: we don't want 
to interrupt
          assert popup.styles.display == "none"
-@@ -329,3 +353,3 @@
+@@ -373,6 +397,6 @@ async def test_does_not_trigger_completi
+         # get back to the message with path completion; ensure again
+         await pilot.press("up")
          await pilot.pause(0.1)
 -        assert chat_input.value == "Check @src/main.py"
 +        assert await _wait_until(pilot, lambda: chat_input.value == "Check 
@src/main.py")
          await pilot.pause(0.2)
+         assert popup.styles.display == "none"
 

Reply via email to