diff --git a/.vscode/launch.json b/.vscode/launch.json index 53a02b4..f63f9e5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,5 +1,5 @@ { - "version": "1.0.5", + "version": "1.0.6", "configurations": [ { "name": "ACP Server", diff --git a/CHANGELOG.md b/CHANGELOG.md index 430424f..115e7a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,27 +5,62 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## v1.0.0 +## [1.0.6] - 2025-12-10 -- Initial release +### Fixed -## v1.0.1 +- add missing steps in bump_version script +- move `pytest-xdist` to dev dependencies +- take into account config for bash timeout -- Fix update notification +### Changed -## v1.0.2 +- improve textual performance +- improve README: + - improve windows installation instructions + - update default system prompt reference + - document MCP tool permission configuration -- Fix setup flow for vibe-acp builds +## [1.0.5] - 2025-12-10 -## v1.0.3 +### Fixed + +- Fix streaming with OpenAI adapter + +## [1.0.4] - 2025-12-09 + +### Changed + +- Rename agent in distribution/zed/extension.toml to mistral-vibe + +### Fixed + +- Fix icon and description in distribution/zed/extension.toml + +### Removed + +- Remove .envrc file + +## [1.0.3] - 2025-12-09 + +### Added - Add LICENCE symlink in distribution/zed for compatibility with zed extension release process -## v1.0.4 +## [1.0.2] - 2025-12-09 -- Remove .envrc file -- Rename agent in distribution/zed/extension.toml to mistral-vibe, fix icon and description +### Fixed -## v1.0.5 +- Fix setup flow for vibe-acp builds -- Fix streaming with OpenAI adapter +## [1.0.1] - 2025-12-09 + +### Fixed + +- Fix update notification + +## [1.0.0] - 2025-12-09 + +### Added + +- Initial release diff --git a/README.md b/README.md index ef3b14a..1f08fe8 100644 --- a/README.md +++ b/README.md @@ -24,17 +24,23 @@ Mistral Vibe is a command-line coding assistant powered by Mistral's models. It > [!WARNING] > Mistral Vibe works on Windows, but we officially support and target UNIX environments. -## Installation - -Vibe requires Python 3.12 or higher. - ### One-line install (recommended) +**Linux and macOS** + ```bash -# On Linux and macOS curl -LsSf https://mistral.ai/vibe/install.sh | bash ``` +**Windows** + +First, install uv +```bash +powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" +``` + +Then, use uv command below. + ### Using uv ```bash @@ -157,7 +163,7 @@ Vibe supports multiple ways to configure your API keys: ### Custom System Prompts -You can create custom system prompts to replace the default one (`prompts/core.md`). Create a markdown file in the `~/.vibe/prompts/` directory with your custom prompt content. +You can create custom system prompts to replace the default one (`prompts/cli.md`). Create a markdown file in the `~/.vibe/prompts/` directory with your custom prompt content. To use a custom system prompt, set the `system_prompt_id` in your configuration to match the filename (without the `.md` extension): @@ -244,6 +250,17 @@ Key fields: - `command`: Command to run for stdio transport - `args`: Additional arguments for stdio transport +MCP tools are named using the pattern `{server_name}_{tool_name}` and can be configured with permissions like built-in tools: + +```toml +# Configure permissions for specific MCP tools +[tools.fetch_server_get] +permission = "always" + +[tools.my_http_server_query] +permission = "ask" +``` + ### Enable/disable tools with patterns You can control which tools are active using `enabled_tools` and `disabled_tools`. diff --git a/distribution/zed/extension.toml b/distribution/zed/extension.toml index 46d1fd0..c1df053 100644 --- a/distribution/zed/extension.toml +++ b/distribution/zed/extension.toml @@ -1,7 +1,7 @@ id = "mistral-vibe" name = "Mistral Vibe" description = "Mistral's open-source coding assistant" -version = "1.0.5" +version = "1.0.6" schema_version = 1 authors = ["Mistral AI"] repository = "https://github.com/mistralai/mistral-vibe" @@ -11,25 +11,25 @@ name = "Mistral Vibe" icon = "./icons/mistral_vibe.svg" [agent_servers.mistral-vibe.targets.darwin-aarch64] -archive = "https://github.com/mistralai/mistral-vibe/releases/download/v1.0.5/vibe-acp-darwin-aarch64-1.0.5.zip" +archive = "https://github.com/mistralai/mistral-vibe/releases/download/v1.0.6/vibe-acp-darwin-aarch64-1.0.6.zip" cmd = "./vibe-acp" [agent_servers.mistral-vibe.targets.darwin-x86_64] -archive = "https://github.com/mistralai/mistral-vibe/releases/download/v1.0.5/vibe-acp-darwin-x86_64-1.0.5.zip" +archive = "https://github.com/mistralai/mistral-vibe/releases/download/v1.0.6/vibe-acp-darwin-x86_64-1.0.6.zip" cmd = "./vibe-acp" # [agent_servers.mistral-vibe.targets.linux-aarch64] -# archive = "https://github.com/mistralai/mistral-vibe/releases/download/v1.0.5/vibe-acp-linux-aarch64-1.0.5.zip" +# archive = "https://github.com/mistralai/mistral-vibe/releases/download/v1.0.6/vibe-acp-linux-aarch64-1.0.6.zip" # cmd = "./vibe-acp" [agent_servers.mistral-vibe.targets.linux-x86_64] -archive = "https://github.com/mistralai/mistral-vibe/releases/download/v1.0.5/vibe-acp-linux-x86_64-1.0.5.zip" +archive = "https://github.com/mistralai/mistral-vibe/releases/download/v1.0.6/vibe-acp-linux-x86_64-1.0.6.zip" cmd = "./vibe-acp" # [agent_servers.mistral-vibe.targets.windows-aarch64] -# archive = "https://github.com/mistralai/mistral-vibe/releases/download/v1.0.5/vibe-acp-windows-aarch64-1.0.5.zip" +# archive = "https://github.com/mistralai/mistral-vibe/releases/download/v1.0.6/vibe-acp-windows-aarch64-1.0.6.zip" # cmd = "./vibe-acp.exe" [agent_servers.mistral-vibe.targets.windows-x86_64] -archive = "https://github.com/mistralai/mistral-vibe/releases/download/v1.0.5/vibe-acp-windows-x86_64-1.0.5.zip" +archive = "https://github.com/mistralai/mistral-vibe/releases/download/v1.0.6/vibe-acp-windows-x86_64-1.0.6.zip" cmd = "./vibe-acp.exe" diff --git a/pyproject.toml b/pyproject.toml index c324b92..b5feb5b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "mistral-vibe" -version = "1.0.5" +version = "1.0.6" description = "Minimal CLI coding agent by Mistral" readme = "README.md" requires-python = ">=3.12" @@ -37,12 +37,12 @@ dependencies = [ "pydantic>=2.12.4", "pydantic-settings>=2.12.0", "python-dotenv>=1.0.0", - "pytest-xdist>=3.8.0", "rich>=14.0.0", "textual>=1.0.0", "tomli-w>=1.2.0", "watchfiles>=1.1.1", "pyperclip>=1.11.0", + "textual-speedups>=0.2.1", ] [project.urls] @@ -87,6 +87,7 @@ dev = [ "typos>=1.34.0", "vulture>=2.14", "pyinstaller>=6.17.0", + "pytest-xdist>=3.8.0", ] [tool.pyright] diff --git a/scripts/bump_version.py b/scripts/bump_version.py index 510a7f6..c608df4 100755 --- a/scripts/bump_version.py +++ b/scripts/bump_version.py @@ -124,10 +124,25 @@ Examples: (f"-{current_version}.zip", f"-{new_version}.zip"), ], ) + # Update .vscode/launch.json + update_hard_values_files( + ".vscode/launch.json", + [(f'"version": "{current_version}"', f'"version": "{new_version}"')], + ) + # Update vibe/core/__init__.py + update_hard_values_files( + "vibe/core/__init__.py", + [(f'__version__ = "{current_version}"', f'__version__ = "{new_version}"')], + ) + # Update tests/acp/test_acp.py + update_hard_values_files( + "tests/acp/test_acp.py", + [(f'version="{current_version}"', f'version="{new_version}"')], + ) subprocess.run(["uv", "lock"], check=True) - print(f"Successfully bumped version from {current_version} to {new_version}") + print(f"\nSuccessfully bumped version from {current_version} to {new_version}") except Exception as e: print(f"Error: {e}", file=sys.stderr) diff --git a/tests/acp/test_acp.py b/tests/acp/test_acp.py index 587aa32..8d38faa 100644 --- a/tests/acp/test_acp.py +++ b/tests/acp/test_acp.py @@ -351,7 +351,7 @@ class TestInitialization: mcpCapabilities=McpCapabilities(http=False, sse=False), ) assert response.result.agentInfo == Implementation( - name="@mistralai/mistral-vibe", title="Mistral Vibe", version="1.0.5" + name="@mistralai/mistral-vibe", title="Mistral Vibe", version="1.0.6" ) vibe_setup_method = next( ( diff --git a/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg b/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg index cd6fb5a..ec53ff0 100644 --- a/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg +++ b/tests/snapshots/__snapshots__/test_ui_snapshot_release_update_notification/test_snapshot_shows_release_update_notification.svg @@ -162,7 +162,7 @@ - + ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ diff --git a/tests/tools/test_manager_get_tool_config.py b/tests/tools/test_manager_get_tool_config.py new file mode 100644 index 0000000..d5a40f5 --- /dev/null +++ b/tests/tools/test_manager_get_tool_config.py @@ -0,0 +1,88 @@ +from __future__ import annotations + +import pytest + +from vibe.core.config import SessionLoggingConfig, VibeConfig +from vibe.core.tools.base import BaseToolConfig, ToolPermission +from vibe.core.tools.manager import ToolManager + + +@pytest.fixture +def config(): + return VibeConfig( + session_logging=SessionLoggingConfig(enabled=False), + system_prompt_id="tests", + include_project_context=False, + ) + + +@pytest.fixture +def tool_manager(config): + return ToolManager(config) + + +def test_returns_default_config_when_no_overrides(tool_manager): + config = tool_manager.get_tool_config("bash") + + assert ( + type(config).__name__ == "BashToolConfig" + ) # due to vibe's discover system isinstance would fail + assert config.default_timeout == 30 # type: ignore[attr-defined] + assert config.max_output_bytes == 16000 # type: ignore[attr-defined] + assert config.permission == ToolPermission.ASK + + +def test_merges_user_overrides_with_defaults(): + vibe_config = VibeConfig( + session_logging=SessionLoggingConfig(enabled=False), + system_prompt_id="tests", + include_project_context=False, + tools={"bash": BaseToolConfig(permission=ToolPermission.ALWAYS)}, + ) + manager = ToolManager(vibe_config) + + config = manager.get_tool_config("bash") + + assert ( + type(config).__name__ == "BashToolConfig" + ) # due to vibe's discover system isinstance would fail + assert config.permission == ToolPermission.ALWAYS + assert config.default_timeout == 30 # type: ignore[attr-defined] + + +def test_preserves_tool_specific_fields_from_overrides(): + vibe_config = VibeConfig( + session_logging=SessionLoggingConfig(enabled=False), + system_prompt_id="tests", + include_project_context=False, + tools={"bash": BaseToolConfig(permission=ToolPermission.ASK)}, + ) + vibe_config.tools["bash"].__pydantic_extra__ = {"default_timeout": 600} + manager = ToolManager(vibe_config) + + config = manager.get_tool_config("bash") + + assert type(config).__name__ == "BashToolConfig" + assert config.default_timeout == 600 # type: ignore[attr-defined] + + +def test_falls_back_to_base_config_for_unknown_tool(tool_manager): + config = tool_manager.get_tool_config("nonexistent_tool") + + assert type(config) is BaseToolConfig + assert config.permission == ToolPermission.ASK + + +def test_applies_workdir_from_vibe_config(tmp_path): + vibe_config = VibeConfig( + session_logging=SessionLoggingConfig(enabled=False), + system_prompt_id="tests", + include_project_context=False, + workdir=tmp_path, + ) + manager = ToolManager(vibe_config) + + config = manager.get_tool_config("bash") + + assert config.workdir == tmp_path + assert config.effective_workdir == tmp_path diff --git a/uv.lock b/uv.lock index cc88afc..c3deb46 100644 --- a/uv.lock +++ b/uv.lock @@ -661,7 +661,7 @@ wheels = [ [[package]] name = "mistral-vibe" -version = "1.0.5" +version = "1.0.6" source = { editable = "." } dependencies = [ { name = "agent-client-protocol" }, @@ -674,10 +674,10 @@ dependencies = [ { name = "pydantic" }, { name = "pydantic-settings" }, { name = "pyperclip" }, - { name = "pytest-xdist" }, { name = "python-dotenv" }, { name = "rich" }, { name = "textual" }, + { name = "textual-speedups" }, { name = "tomli-w" }, { name = "watchfiles" }, ] @@ -691,6 +691,7 @@ dev = [ { name = "pytest-asyncio" }, { name = "pytest-textual-snapshot" }, { name = "pytest-timeout" }, + { name = "pytest-xdist" }, { name = "respx" }, { name = "ruff" }, { name = "twine" }, @@ -710,10 +711,10 @@ requires-dist = [ { name = "pydantic", specifier = ">=2.12.4" }, { name = "pydantic-settings", specifier = ">=2.12.0" }, { name = "pyperclip", specifier = ">=1.11.0" }, - { name = "pytest-xdist", specifier = ">=3.8.0" }, { name = "python-dotenv", specifier = ">=1.0.0" }, { name = "rich", specifier = ">=14.0.0" }, { name = "textual", specifier = ">=1.0.0" }, + { name = "textual-speedups", specifier = ">=0.2.1" }, { name = "tomli-w", specifier = ">=1.2.0" }, { name = "watchfiles", specifier = ">=1.1.1" }, ] @@ -727,6 +728,7 @@ dev = [ { name = "pytest-asyncio", specifier = ">=1.2.0" }, { name = "pytest-textual-snapshot", specifier = ">=1.1.0" }, { name = "pytest-timeout", specifier = ">=2.4.0" }, + { name = "pytest-xdist", specifier = ">=3.8.0" }, { name = "respx", specifier = ">=0.22.0" }, { name = "ruff", specifier = ">=0.14.5" }, { name = "twine", specifier = ">=5.0.0" }, @@ -1523,6 +1525,69 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2f/7a/7f3ea5e6f26d546ee4bd107df8fc9eef9f149dab0f6f15e1fc9f9413231f/textual-6.7.1-py3-none-any.whl", hash = "sha256:b92977ac5941dd37b6b7dc0ac021850ce8d9bf2e123c5bab7ff2016f215272e0", size = 713993, upload-time = "2025-12-01T20:57:23.698Z" }, ] +[[package]] +name = "textual-speedups" +version = "0.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d4/73/bba3e9feae9ca730c32122306ddac61278a8bc47633346eddad9d52a435d/textual_speedups-0.2.1.tar.gz", hash = "sha256:72cf0f7bdeede015367b59b70bcf724ba2c3080a8641ebc5eb94b36ad1536824", size = 10951, upload-time = "2025-11-28T09:38:51.582Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/3d/acf24db3e1f3f218331da770d12ff93ad5d6021143aa7b2dfafff7f3940c/textual_speedups-0.2.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:84d2209fc85b7b06d81de200e46de6b51961e2ea1708cd568059983d7b7b634e", size = 284071, upload-time = "2025-11-28T09:38:01.425Z" }, + { url = "https://files.pythonhosted.org/packages/eb/30/0891458bcd91c36e7f54deb300a7691daf6003f8f7f696aa7a809a09c556/textual_speedups-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aabadeabdd03bce13b55a4c9c927d702160695c3f2f8a1789b95ed0102968a8d", size = 279385, upload-time = "2025-11-28T09:37:56.572Z" }, + { url = "https://files.pythonhosted.org/packages/8e/40/7b870f4dde1df3b2f3cf44147eda9996a8469dde32eb7a8df517943be82f/textual_speedups-0.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37a47c888d9cfdc6b2785844393e250fb268b404ea8eee937ac862b7b1666e82", size = 312100, upload-time = "2025-11-28T09:36:53.556Z" }, + { url = "https://files.pythonhosted.org/packages/b0/36/bc1acea15b42ecb7820dbeebf878fd11e5ce5ee2205cba23eb5db66bc193/textual_speedups-0.2.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3d4c80c6e1d687d4d508de856a0c7c5090e07d964c09701b582cc1f64452f753", size = 317812, upload-time = "2025-11-28T09:37:05.329Z" }, + { url = "https://files.pythonhosted.org/packages/47/b7/9afee0b02706eae5a6ebb5a58e490b15b71e7259c3c730c1b08e4cc8c107/textual_speedups-0.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4523970dfd9d2718fdd293a8ae1d8b098ca65bdd54666416a13d5acbaacdc64a", size = 437546, upload-time = "2025-11-28T09:37:16.687Z" }, + { url = "https://files.pythonhosted.org/packages/9a/9a/4cb41b47c9426e549b9e1510f0937eaeb9333618854ba3cb77e5c656fc5e/textual_speedups-0.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a3129288536be5e5319f3a03525a04e222c46340d448f180d2c4327b2651563", size = 333720, upload-time = "2025-11-28T09:37:28.244Z" }, + { url = "https://files.pythonhosted.org/packages/01/b9/a626b2ea864293bca999565ae0040315f0cd7ffb9147dfb30467de3ec1a0/textual_speedups-0.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5e43f0af17ef8834ecdf1c1be466eca441970547b5df2e6c17eea301290118d", size = 311174, upload-time = "2025-11-28T09:37:49.684Z" }, + { url = "https://files.pythonhosted.org/packages/e9/39/ed6a9ef7c357f95504a151d4df376eee6a24056bbdf7009bfe25815cc437/textual_speedups-0.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1b271489001115ef18dbf92e68cc5f081285a7758e63daef9894c83244b8700c", size = 335118, upload-time = "2025-11-28T09:37:39.452Z" }, + { url = "https://files.pythonhosted.org/packages/e9/54/396bdc7f9827a6d8abea2fffceb6f17e23dcb0f1e9ff5b6c102714b1ec6d/textual_speedups-0.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:68c3a20b2e7b8d33c292fcd8d613e6f2e0e25ff131d988c73646757f50a37f3f", size = 493537, upload-time = "2025-11-28T09:38:07.187Z" }, + { url = "https://files.pythonhosted.org/packages/2b/0f/b7eb6f4366c19b7baeec3e9b8cc91d817c36f0c43f91a5e8ed158fccb6da/textual_speedups-0.2.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:50bcc9f315930ab0214ee87847f901fcdd71d2972d683502a495f6266489c208", size = 585045, upload-time = "2025-11-28T09:38:19.771Z" }, + { url = "https://files.pythonhosted.org/packages/f7/82/1f21d68a711b178ba7e91517b7c920f97b7bac4dc7104da77c9e06bd0ded/textual_speedups-0.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7fede4ded345dc7205cf04e0157179bb37c5477d2d8193c1cbe2171256e63fdb", size = 514284, upload-time = "2025-11-28T09:38:31.791Z" }, + { url = "https://files.pythonhosted.org/packages/f4/b5/971e3274d809a36a56bd17b8c2d908e3e9c11d02ccbc57a717b897325623/textual_speedups-0.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:70f07dc375244d6eb461df2405413b2d67cabf7265a255213e70dcaae1ae6ff9", size = 482176, upload-time = "2025-11-28T09:38:43.419Z" }, + { url = "https://files.pythonhosted.org/packages/d8/4d/bf4e19bdffb137a4c2a027ffde32b77a1465da5a2c8470b0058b9a156486/textual_speedups-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:19f4d1b13da38ba0e7a6c87815447b114301670f9d4e6f9a7bdf9d4ae9f5f926", size = 159927, upload-time = "2025-11-28T09:38:54.56Z" }, + { url = "https://files.pythonhosted.org/packages/12/5b/485f122aad6a084ad4b95483078181565fe17c65b5420db13f744f8c984f/textual_speedups-0.2.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:55cc5a86ceb7cf82e0089a6d45daa3c3ea9248bb2a2fbcde40f9aeb562386a24", size = 284044, upload-time = "2025-11-28T09:38:02.899Z" }, + { url = "https://files.pythonhosted.org/packages/fd/ab/af8eb2c53b65bd1f868109602ae11daac34d0889c80380b556f644793af5/textual_speedups-0.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c762c60275dce06b9c9bde4173cefef950798877da0aac46538ccd0d2ffb2f43", size = 279446, upload-time = "2025-11-28T09:37:57.822Z" }, + { url = "https://files.pythonhosted.org/packages/9a/d8/aab66c0401118633ac3121d4f79695e86d37aae3b2ebd49a626d034ba64e/textual_speedups-0.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42172f4b7742988d9ff28098600b8a4a86a7e86ba39fcc3c779a93b98ef31abc", size = 311522, upload-time = "2025-11-28T09:36:54.59Z" }, + { url = "https://files.pythonhosted.org/packages/cc/3f/3376f7caba0caecb643f7cede803fd4ba15b8262ea8b479201e3a6599768/textual_speedups-0.2.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d2b58a100a3634e24bb532ad70602439bf358ea68687eb58eb18b05d699136e9", size = 316844, upload-time = "2025-11-28T09:37:06.52Z" }, + { url = "https://files.pythonhosted.org/packages/22/39/a6745c82a379e0a924f788e5a3ab7c29792c9d9847cec88e7f95d8c2c751/textual_speedups-0.2.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7bded0beea2e344c0a2eea378235c61a8cab66e3eee8c5f6a92841b8c83d8b42", size = 438347, upload-time = "2025-11-28T09:37:17.828Z" }, + { url = "https://files.pythonhosted.org/packages/77/65/f030a5e104faed6339d2be7dedcf8e880b463860fe5b881a52cdfb88e0a5/textual_speedups-0.2.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7a2cc60b3b87b684fdf9059f2f952dfc0a41e351018331862ddbb76b87f86a1", size = 334125, upload-time = "2025-11-28T09:37:29.386Z" }, + { url = "https://files.pythonhosted.org/packages/65/45/38a83d71467dab3e4dff6423ce2daa57da67032cfd918a6f697e31e6807c/textual_speedups-0.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1389c87c4e1a071ba7ef0a2189d6989b753893ade56fea2e46bda5579f9e1844", size = 310870, upload-time = "2025-11-28T09:37:50.872Z" }, + { url = "https://files.pythonhosted.org/packages/97/19/543c077c5b7164a66e98778ec37da322d6cb126f7873ab3523a7974f47cc/textual_speedups-0.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3760151da33f317f0d99d0191b1da1ccb1464e8d172207c857b6f25e67bb9ce2", size = 334639, upload-time = "2025-11-28T09:37:40.646Z" }, + { url = "https://files.pythonhosted.org/packages/df/53/416919d1a944443d0b98e21c4d12c43f623e55b5faa27db45e62bf8a8fd8/textual_speedups-0.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c6f9b5a76e4df9614313be8b32192705f41c24b1fdac2a63e5d8fb8a82098f4", size = 492669, upload-time = "2025-11-28T09:38:08.653Z" }, + { url = "https://files.pythonhosted.org/packages/68/dd/234f7c4aa735f7ab37f0c074b35f1a152822b2bc08d3ccee76a6af4b1dda/textual_speedups-0.2.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:472bfecd1de0fecdfb8ac27f0543988f54f9f9e7ec10e4bd9ec1817c9e97ebf2", size = 584269, upload-time = "2025-11-28T09:38:21.246Z" }, + { url = "https://files.pythonhosted.org/packages/cc/ec/a9609d4a3b4bad84acc36eab8f8e59e9c8fe234341a57ced7679d784a3a2/textual_speedups-0.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:633ede114e6d24ea1fe99b6165242b233569008d0f4e30fb1e4484137dd6ec8a", size = 513963, upload-time = "2025-11-28T09:38:33.005Z" }, + { url = "https://files.pythonhosted.org/packages/01/d9/dc46c490a16fae66a0ac4f6ae087937cc7644cd80a7820aafcdcfd73e4e1/textual_speedups-0.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:85704fe03f0df3314354815d5edcc58121003e25a4ecaab7d9ab3ab8f91e9abc", size = 482097, upload-time = "2025-11-28T09:38:44.56Z" }, + { url = "https://files.pythonhosted.org/packages/ff/47/fb88052dbb1e2dd9cd3a46bb235fe0e9dfb0423389dc19b99f517dfafae9/textual_speedups-0.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:f360211bde6e58e0e7c9b594ee317682ec2812d8f3613087421a42142ed69bdd", size = 159731, upload-time = "2025-11-28T09:38:55.557Z" }, + { url = "https://files.pythonhosted.org/packages/48/15/0bbb3b4516ce0b6fa040b38483a1c442cfe8bcb9dfcf819063cf0e569d96/textual_speedups-0.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d132064312e9a79e44612ba227ddea071803e9f2bb725e17e2b96c2e2d707f8a", size = 312763, upload-time = "2025-11-28T09:36:55.989Z" }, + { url = "https://files.pythonhosted.org/packages/8a/8d/fd65c4b5d720cbff4ac0666074b3de37bc05d594ea86ce946bfbc84fbaec/textual_speedups-0.2.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:40a409f9f1ada86f8ea25908bdfea0323122fbfc1283437b95541c91b05c6071", size = 319133, upload-time = "2025-11-28T09:37:07.649Z" }, + { url = "https://files.pythonhosted.org/packages/bf/23/406690d7b19bac5963976ade0419ebadba28f4c6818a13f4359f4ef71d2c/textual_speedups-0.2.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:487bd44791ccab54b13db1c2359380fb58e8c8aa2a3c7f976b80fe552060bf59", size = 441656, upload-time = "2025-11-28T09:37:19.32Z" }, + { url = "https://files.pythonhosted.org/packages/aa/40/fe309db81d77491a3f2f9b2648d13c2cb0de462f2ca1c12237d5359e5d2c/textual_speedups-0.2.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:31fd676c50114df04ab3d84fc76741d6b8542db477d1887c5d5ef6a9d1c7d06b", size = 335020, upload-time = "2025-11-28T09:37:30.595Z" }, + { url = "https://files.pythonhosted.org/packages/31/11/2eb96221e278a5c51487d7489f88d5a70f01b3e0f6b3de243ff69e7b9ad4/textual_speedups-0.2.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:72fc01e98be7ab7bb251be6e7f7d5dbff409d9242ce729e0d7786268876f3e63", size = 494418, upload-time = "2025-11-28T09:38:09.874Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2f/098eed1da86a9897244ba07a23b2b7d94b506c9826ede7d67e5e365ba109/textual_speedups-0.2.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f5c9d36c952f86857625833717ee49e7329685d435d6d0764b6998c6189a0c3d", size = 586312, upload-time = "2025-11-28T09:38:22.553Z" }, + { url = "https://files.pythonhosted.org/packages/cf/1b/67b399255357db398d2ea24f4e1dc9fb55f691546328b50f3ff8c26fb697/textual_speedups-0.2.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:476331a1180c57b49a4f553840b195a83bcd3a9ff2c199ad7baa975447d3db05", size = 516036, upload-time = "2025-11-28T09:38:34.275Z" }, + { url = "https://files.pythonhosted.org/packages/94/7d/5c05f0237ea0665dcfe88982b45148a64883cb78bbf5b6bb1beb66265bb2/textual_speedups-0.2.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bdd9298bd66853b2df37a766193d28bdc0de86b80067fd90737fd9405bd5a727", size = 483602, upload-time = "2025-11-28T09:38:45.728Z" }, + { url = "https://files.pythonhosted.org/packages/91/ca/b878beabe3ad2c4aa958f55cb32ba34e7badaa09f73c6e94c87195eb531e/textual_speedups-0.2.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:99a88f44c1b846d51dd115b5fb4dbf97bdef83e9f98a84efec16922a5974e230", size = 278485, upload-time = "2025-11-28T09:37:58.941Z" }, + { url = "https://files.pythonhosted.org/packages/f1/af/9b49ea67a5e9a6f54600deb63bd7c0fd7dbe4a3592300207d41c52762a1b/textual_speedups-0.2.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d2036752ff0df77972b157e71dd942fd75871d9c4feca751f222310bff7c17a", size = 311262, upload-time = "2025-11-28T09:36:57.371Z" }, + { url = "https://files.pythonhosted.org/packages/81/88/6397efb6bf31c0c815ad12f63e84e3a3f952cab5b4dbdadad3a368ced436/textual_speedups-0.2.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:267c44974ea63e9742ea6cbb65f96d5dbdd09b2f9979823a4b7f664614dd21af", size = 317933, upload-time = "2025-11-28T09:37:08.745Z" }, + { url = "https://files.pythonhosted.org/packages/b2/ce/e687d556e6a072b14a6c46ed647a9d5cf862df24c9639c17bd66c0655908/textual_speedups-0.2.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd3f19c6fd7148b6ba86c4c8bde7fdbf96b33687dc42872b8da2fdf67f5ab6d3", size = 438268, upload-time = "2025-11-28T09:37:20.429Z" }, + { url = "https://files.pythonhosted.org/packages/ec/06/e111d6d5e6a5f927ff3ee940c08d4b904143213a5dc2a325832f66848b9b/textual_speedups-0.2.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6245ea2c4883815ed23ecaf852e4de3d2d99e5f082790e780202705730c30b9a", size = 333978, upload-time = "2025-11-28T09:37:31.777Z" }, + { url = "https://files.pythonhosted.org/packages/b3/20/7030634f4e2c5f2c410cf8e6fbcad6e278d0a6dc7ead5fcf31d497951fce/textual_speedups-0.2.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6aaade447724543c60e546542ff91224028992ce4a2a071c81b1927cead114b3", size = 310102, upload-time = "2025-11-28T09:37:51.982Z" }, + { url = "https://files.pythonhosted.org/packages/15/34/7b2b7d831d3668d27285e21c45ff03fab5c9b41092948995562517e53f8b/textual_speedups-0.2.1-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:821d3e57014d0d426c28fc8da4adaa0829f5cdf3ea133559ce6c64baf3aa98d6", size = 335335, upload-time = "2025-11-28T09:37:42.792Z" }, + { url = "https://files.pythonhosted.org/packages/49/90/909a6fd6cf29e323ae6102474ed254e037ac7d1c534e33860ecd54013d8a/textual_speedups-0.2.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fecfdc25439a890dfb9f7357f2d854ef801c5a6484b595dde1baf6a15d20b945", size = 492172, upload-time = "2025-11-28T09:38:11.021Z" }, + { url = "https://files.pythonhosted.org/packages/ad/7f/2a50d7c712ad2b6495344bf9f1d0a805291b1cb53595e7ad7b749d253c29/textual_speedups-0.2.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:0df559abaa14324757e8995e27c83171673377effd7348350f2d1b852eb0e8c1", size = 584840, upload-time = "2025-11-28T09:38:23.757Z" }, + { url = "https://files.pythonhosted.org/packages/1e/a6/ad6b451b5fa550ed13e7084440b9d89bb689b8aa5afe1b26b83b49540057/textual_speedups-0.2.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ebc5094080c61d06c71011da6c7522e51635d1425bfa14d693bca6059e64b795", size = 514648, upload-time = "2025-11-28T09:38:35.774Z" }, + { url = "https://files.pythonhosted.org/packages/c2/45/3c81292f786b57dca7468da732dca902dc7ca1a280b0d785ee7c721f5dc4/textual_speedups-0.2.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5fee92c2e442b86644769011dfbd4f0dbcd43490eecd577735a09a751f3d4a31", size = 481640, upload-time = "2025-11-28T09:38:46.902Z" }, + { url = "https://files.pythonhosted.org/packages/a2/33/1894d2433d0e852177857c3a328346aae626d096e34a1064691ccf04eca1/textual_speedups-0.2.1-cp314-cp314-win32.whl", hash = "sha256:8ffcf6711869f4241a751aacc055f46c842fb633000964c94e3d1f1bf4b887c0", size = 151110, upload-time = "2025-11-28T09:38:58.758Z" }, + { url = "https://files.pythonhosted.org/packages/1b/b3/0b3957b1187c657794d36529d7a0d7e81e2a8af6f68d0e0b57f53f347db1/textual_speedups-0.2.1-cp314-cp314-win_amd64.whl", hash = "sha256:1889ae903263c47f76905443a5274d3cceacf5ee218af8c79ef24598c54ac70e", size = 159722, upload-time = "2025-11-28T09:38:56.653Z" }, + { url = "https://files.pythonhosted.org/packages/a2/67/0d79c23d74736b51a84a8bb2adcf538a4f4c01b681f916a2f6c12aebc9a1/textual_speedups-0.2.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b03ffba57b8d2eb991a2edcc4a873096228ab2c1c3ba8577e502204a721037c8", size = 312683, upload-time = "2025-11-28T09:36:58.758Z" }, + { url = "https://files.pythonhosted.org/packages/67/d3/9b19fcaaf27799846d89a24b5d4e432425eb3ea4811e61a358685ebcde62/textual_speedups-0.2.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03a8dc93c983215e187c414a66e5d338c8805f30180b8b845c05914e37a1b315", size = 319134, upload-time = "2025-11-28T09:37:09.881Z" }, + { url = "https://files.pythonhosted.org/packages/44/18/fb492f764e756353e11ce82691eea04bd57d43e7eae86e96a53f49c8830d/textual_speedups-0.2.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3634667a035134cda18890a623f9fc561ff3c22d9a6e97c6244e52047251f454", size = 441148, upload-time = "2025-11-28T09:37:21.541Z" }, + { url = "https://files.pythonhosted.org/packages/ba/f5/f3f8d27a85de6ba74a97b19f5174b44df9cf4d7188792c39017a0f872937/textual_speedups-0.2.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5786c2c56cf0e99ad89481f1464ec002d1bfe3adbd5bcb5f1f9b9fd03a7cc063", size = 335003, upload-time = "2025-11-28T09:37:32.953Z" }, + { url = "https://files.pythonhosted.org/packages/eb/53/e74500c99414d44565f1c26c906f382085ce98ba33c986b4ffede69102b9/textual_speedups-0.2.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9d05bdd2c760833c9ed8d1fffb7cca2e293c15031e53e270e06766dbc96771fc", size = 494039, upload-time = "2025-11-28T09:38:12.511Z" }, + { url = "https://files.pythonhosted.org/packages/ff/9a/b834df281395d5d3311a627ac8587e61f0e4bcdf53c1df451dbd5822e1e0/textual_speedups-0.2.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:7dc58e59d740e66d1e0a9ce18835ee0e6a72a61bf0a4c1afce38273e217fdf27", size = 586432, upload-time = "2025-11-28T09:38:25.238Z" }, + { url = "https://files.pythonhosted.org/packages/6b/46/375d5b63a68a48770bf556ca364ef9d9cd79574f3b5dee2c542706177d28/textual_speedups-0.2.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e6e8c74a63080a50a95f26e87818c66d8507de21c6d610ed049f91b84402aafa", size = 516212, upload-time = "2025-11-28T09:38:36.935Z" }, + { url = "https://files.pythonhosted.org/packages/06/02/80c118df98fa8ef84fa8e690b18c20302dc697c59dfee8a9667b72424aa6/textual_speedups-0.2.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5fd85522114aec21c3915725992401e2bf6372ae5b1e3b2ebd85e1c3c7115885", size = 483699, upload-time = "2025-11-28T09:38:48.087Z" }, +] + [[package]] name = "tomli-w" version = "1.2.0" diff --git a/vibe/cli/textual_ui/app.tcss b/vibe/cli/textual_ui/app.tcss index 9e61b04..ad3a9b9 100644 --- a/vibe/cli/textual_ui/app.tcss +++ b/vibe/cli/textual_ui/app.tcss @@ -58,6 +58,7 @@ Screen { } #messages { + layout: stream; width: 100%; height: auto; text-align: left; diff --git a/vibe/core/__init__.py b/vibe/core/__init__.py index 4d7dc2c..78604af 100644 --- a/vibe/core/__init__.py +++ b/vibe/core/__init__.py @@ -1,6 +1,6 @@ from __future__ import annotations __all__ = ["__version__", "run_programmatic"] -__version__ = "1.0.5" +__version__ = "1.0.6" from vibe.core.programmatic import run_programmatic diff --git a/vibe/core/tools/base.py b/vibe/core/tools/base.py index de4ff6f..85bab0a 100644 --- a/vibe/core/tools/base.py +++ b/vibe/core/tools/base.py @@ -61,6 +61,8 @@ class BaseToolConfig(BaseModel): denylist: Patterns that automatically deny tool execution. """ + model_config = ConfigDict(extra="allow") + permission: ToolPermission = ToolPermission.ASK workdir: Path | None = Field(default=None, exclude=True) allowlist: list[str] = Field(default_factory=list)