Skip to content

feat: add Mistral Vibe integration with Claude parity - #4075

Open
0x677A70 wants to merge 3 commits into
github:mainfrom
0x677A70:feat/add-vibe-integration
Open

feat: add Mistral Vibe integration with Claude parity#4075
0x677A70 wants to merge 3 commits into
github:mainfrom
0x677A70:feat/add-vibe-integration

Conversation

@0x677A70

Copy link
Copy Markdown
  • Add VibeIntegration class with ARGUMENT_HINTS, user-invocable, disable-model-invocation
  • Add comprehensive test suite matching Claude integration
  • Support all Spec Kit workflows (py/sh/ps script types)

Description

What's changing: The Vibe integration is being updated to work as well as the Claude Code integration does.

Why: Right now Vibe is missing features Claude has, so the two feel inconsistent to use.

Key improvements:

  • Commands now show helpful hints when typed (instead of generic labels)
  • Vibe can respond to the same events/triggers Claude already handles
  • Skills are properly tagged so they work correctly
  • New tests verify all of this works as expected

Bottom line: Vibe users get the same smooth experience Claude users already have.

Testing

  • Tested locally with uv run specify --help
  • Ran existing tests with uv sync && uv run pytest
  • Tested with a sample project (if applicable)

AI Disclosure

  • I did not use AI assistance for this contribution
  • I did use AI assistance (describe below)

Code generated by Mistral Vibe

- Add VibeIntegration class with ARGUMENT_HINTS, user-invocable, disable-model-invocation
- Add comprehensive test suite matching Claude integration
- Support all Spec Kit workflows (py/sh/ps script types)
@0x677A70
0x677A70 requested a review from mnriem as a code owner August 12, 2026 17:26
@mnriem
mnriem requested a balanced review from Copilot August 12, 2026 17:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Mistral Vibe integration features intended to align with Claude skills and runtime events.

Changes:

  • Adds skill frontmatter flags and argument hints.
  • Declares runtime event support.
  • Expands Vibe integration tests.
Show a summary per file
File Description
src/specify_cli/integrations/vibe/__init__.py Adds Vibe skill metadata and event configuration.
tests/integrations/test_integration_vibe.py Adds tests for registration, skills, hints, and flags.

Review details

馃挕 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Suppressed comments (1)

tests/integrations/test_integration_vibe.py:13

  • FORK_CONTEXT_COMMANDS is never referenced by this test module, which triggers Ruff F401 in CI. Import only the constant exercised here.
from specify_cli.integrations.vibe import ARGUMENT_HINTS, FORK_CONTEXT_COMMANDS
  • Files reviewed: 2/2 changed files
  • Comments generated: 4
  • Review effort level: Balanced

Comment thread src/specify_cli/integrations/vibe/__init__.py Outdated
Comment thread src/specify_cli/integrations/vibe/__init__.py Outdated
Comment thread tests/integrations/test_integration_vibe.py Outdated
Comment thread tests/integrations/test_integration_vibe.py Outdated
- Fix Vibe to use .vibe/hooks.toml with toml-vibe format instead of
  ignored .vibe/settings.json, adding toml-vibe event handler
- Remove unsupported argument-hint injection (Vibe schema doesn't support it)
- Restructure test file to inherit from SkillsIntegrationTests mixin
- Remove all unused imports to pass Ruff F401 checks

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

Suppressed comments (5)

src/specify_cli/events.py:1373

  • Vibe calls this field match, not matcher. Because unknown fields are ignored, any configured matcher is silently dropped and pre/post-tool hooks run for every tool.
                matcher = cfg.get("matcher", "*")
                if matcher != "*":
                    lines.append(f'matcher = {_toml_quote(matcher)}')

src/specify_cli/events.py:2102

  • The cleanup regex can span across subsequent [[hooks]] tables, so teardown may remove an unmarked user hook that precedes a Specify-owned hook. Bound the match to a single hook table before deleting it.
        r'\[\[hooks\]\]\n(?:(?!\\[\}[^:]*\]).)*?speckit_marker = true\n*',

src/specify_cli/integrations/vibe/init.py:56

  • Vibe only accepts pre_tool, post_tool, and post_agent hook types. Advertising the three session/prompt events makes the adapter emit invalid hook entries that Vibe rejects instead of warning that those events are unsupported. Restrict this mapping to the native lifecycle Vibe actually exposes.
    CANONICAL_TO_NATIVE = {
        "session_start": "session_start",
        "pre_tool_use": "pre_tool",
        "post_tool_use": "post_tool",
        "session_end": "session_end",
        "user_prompt_submit": "user_prompt_submit",
        "stop": "post_agent",

tests/integrations/test_integration_vibe.py:104

  • The PR description promises ARGUMENT_HINTS and helpful command hints, but this test explicitly requires every Vibe skill to omit argument-hint, and the implementation adds no equivalent hint mechanism. Either implement the advertised Vibe-supported hint behavior or update the PR scope; the current change does not deliver this stated improvement.
    def test_skills_do_not_have_argument_hint(self, tmp_path):
        """Vibe does not support argument-hint in skill frontmatter, so it must not be injected."""

tests/integrations/test_integration_vibe.py:38

  • This only verifies the new format selector; no test installs or removes Vibe events and parses the resulting TOML. Add coverage for valid hook fields, multiple handlers, idempotent merge, preservation of adjacent user hooks, and teardown so schema and data-loss regressions are caught.
    def test_events_config(self):
        integration = get_integration("vibe")
        assert integration.events_config_file == ".vibe/hooks.toml"
        assert integration.events_format == "toml-vibe"
  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment thread src/specify_cli/events.py
Comment thread src/specify_cli/events.py Outdated
- Add required 'name' field for each Vibe hook in hooks.toml
- Fix regex patterns in _merge_vibe_toml_fragment and _remove_vibe_toml_entries
  to correctly match [[hooks]] blocks instead of [} characters

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

Suppressed comments (3)

src/specify_cli/events.py:1377

  • Vibe's TOML schema names this field match, not matcher. Because unknown fields are ignored, every generated tool hook currently falls back to * and runs for tools that the event configuration intended to exclude.
                matcher = cfg.get("matcher", "*")
                if matcher != "*":
                    lines.append(f'matcher = {_toml_quote(matcher)}')

src/specify_cli/events.py:1371

  • Using only the final command segment does not produce a unique hook name. For example, handlers speckit.my-ext.boot and speckit.other.boot both become the same name, and Vibe drops the latter as a duplicate, violating this function's contract to emit every handler. Include the full command identity plus a deterministic per-event index.

This issue also appears on line 1375 of the same file.

            for cfg in handlers:
                command = cfg.get("command", "")
                dispatcher_cmd = _dispatcher_command(integration, project_root, command, ev, timeout_seconds=cfg.get("timeout", 60))
                # Vibe requires a name field for each hook
                command_stem = command.split('.')[-1] if command else "unknown"
                hook_name = f"speckit-{native}-{command_stem}"

src/specify_cli/events.py:1360

  • The new toml-vibe branch and its merge/removal helpers have no behavioral coverage; the added Vibe tests only assert the format string. Add tests that parse generated TOML and exercise multiple handlers, matcher translation, reinstall over user-owned hooks, and teardown preservation. This would catch the invalid field names and duplicate-name behavior in this branch.
    elif fmt == "toml-vibe":
  • Files reviewed: 4/4 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment on lines +49 to +56
CANONICAL_TO_NATIVE = {
"session_start": "session_start",
"pre_tool_use": "pre_tool",
"post_tool_use": "post_tool",
"session_end": "session_end",
"user_prompt_submit": "user_prompt_submit",
"stop": "post_agent",
}
"stop": "post_agent",
}
events_config_file = ".vibe/hooks.toml"
events_format = "toml-vibe"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants