Skip to content

feat(adapters): add Mistral Vibe platform adapter - #1044

Open
xavierpestel-ai wants to merge 2 commits into
mksglu:mainfrom
xavierpestel-ai:feat/mistral-vibe-adapter
Open

feat(adapters): add Mistral Vibe platform adapter#1044
xavierpestel-ai wants to merge 2 commits into
mksglu:mainfrom
xavierpestel-ai:feat/mistral-vibe-adapter

Conversation

@xavierpestel-ai

Copy link
Copy Markdown

Summary

Adds support for Mistral Vibe (mistralai/mistral-vibe) — Mistral AI's official open-source coding CLI. Package mistral-vibe on PyPI, command vibe, Python 3.12+, MIT-licensed.

Zero changes required in Vibe itself — the integration uses Vibe's stable public surfaces: [[hooks]] array tables in ~/.vibe/hooks.toml and [[mcp_servers]] in ~/.vibe/config.toml.

Why

Vibe ships with MCP support and a hook system nearly identical to Claude Code / Codex / Kimi (JSON stdin/stdout over subprocesses), so it slots naturally into the existing adapter pattern. It's the 18th supported platform and the first Python-based one in the JSON-stdio group.

What's added

  • Adapter (src/adapters/mistral-vibe/)
    • index.tsMistralVibeAdapter implementing HookAdapter
    • hooks.ts — hook type constants + wire-protocol docstring
    • paths.tsresolveVibeConfigDir() honoring $VIBE_HOME
    • config.ts — thin re-exports (parity with sibling adapters)
  • Hook scripts (hooks/mistral-vibe/{pretooluse,posttooluse}.mjs) translating Vibe wire format ↔ context-mode routing/session pipelines
  • Vibe formatter in hooks/core/formatters.mjs + namer in hooks/core/tool-naming.mjs
  • Registration in types.ts, detect.ts (env-var, config-dir, session-dir, getAdapter switch), client-map.ts, cli.ts (hook dispatcher), and hooks/core/platform-detect.mjs (hook-side mirror)
  • Routing instructions at configs/mistral-vibe/AGENTS.md
  • Tests (tests/adapters/mistral-vibe.test.ts, 49 tests)
  • Docs: README install section + docs/platform-support.md platform section

Design notes

Aspect Value Rationale
Paradigm json-stdio (TOML [[hooks]]) Same subprocess+JSON model as Claude Code / Codex / Kimi, but hooks live in hooks.toml distinct from config.toml
Capabilities preToolUse: true, postToolUse: true, canModifyArgs: true Vibe exposes pre_tool rewrite via hook_specific_output.tool_input and deny via decision: "deny"
Not supported preCompact, sessionStart, canModifyOutput, canInjectSessionContext Vibe exposes only pre_tool, post_tool, post_agent. post_tool additional_context is append-only, not a rewrite
Detection $VIBE_HOME env var + ~/.vibe/ dir See caveat below re. MCP clientInfo.name
Instruction file AGENTS.md Vibe's default (same convention as Codex / OpenCode)

MCP clientInfo caveat

Vibe uses the MCP SDK's default Implementation(name="mcp", version="0.1.0") because it does not pass client_info to ClientSession (see vibe/core/tools/mcp/tools.py). That name is too generic to safely map to any platform, so detection relies on env-var + config-dir signals instead. The client-map.ts entries for "mistral-vibe" / "Mistral Vibe" / "vibe" are placeholders that will match if Vibe ever ships a proper client_info.

Coexistence with rtk

Both context-mode and rtk (a token-optimization CLI) register pre_tool bash hooks. Vibe runs hooks in TOML declaration order — users should keep context-mode-pretool first so redirected commands never reach rtk. The two coexist cleanly; context-mode's redirect is a no-op passthrough when it doesn't apply. This is documented in configs/mistral-vibe/AGENTS.md and the README section.

Session continuity trade-off

Vibe lacks PreCompact / SessionStart hooks, so full snapshot-based session restore is not available. The routing block in AGENTS.md provides model-side memory queries (via ctx_search on the persisted session events) as the compaction-recovery workaround. Session events are captured normally via post_tool and searchable through ctx_search — only the automatic "restore after compact" pipeline is missing.

Testing

Ran the full suite before and after:

Total Passed Failed
Baseline (main) 4742 4688 25
With PR 4791 4737 25
Delta +49 +49 0
  • 49 new adapter tests all pass
  • 25 pre-existing failures on main still fail on this branch (all env-related: git commit without local user.name, IDEA_INITIAL_DIRECTORY unset, macOS-specific casing checks). Zero regressions caused by this PR.
  • Small fix to tests/util/project-dir-matrix.test.ts: added "mistral-vibe" to the platform sanity list (the file's existing comment says "When adding a new adapter, append it here").
  • Typecheck (npm run typecheck) ✅
  • Build (npm run buildtsc + esbuild bundles + assert-bundle + assert-asymmetric-drift) ✅

End-to-end validation

Verified against a live vibe --output json session with the adapter's hooks.toml + config.toml installed:

  • context-mode-pretool hook fires on every bash invocation (status ok, ~1ms)
  • context-mode-posttool hook fires on every tool call (status ok, ~80ms)
  • MCP server reachable — context-mode_ctx_stats returned context-mode < 1 min 0 calls ... v1.0.169
  • Hook JSON wire format compatible in both directions

Config snippets (from the manual test, now generated by configureAllHooks):

# ~/.vibe/config.toml
[[mcp_servers]]
name = "context-mode"
transport = "stdio"
command = "context-mode"
# ~/.vibe/hooks.toml
[[hooks]]
name = "context-mode-pretool"
type = "pre_tool"
match = "bash"
command = "context-mode hook mistral-vibe pretooluse"
timeout = 30.0

[[hooks]]
name = "context-mode-posttool"
type = "post_tool"
command = "context-mode hook mistral-vibe posttooluse"
timeout = 30.0

References

Checklist (per CONTRIBUTING.md)

  • TDD: 49 tests added (capabilities, parsing, formatting, config paths, hook generation, validation, MCP registration, CLI probing)
  • Test file organization respected (added to tests/adapters/mistral-vibe.test.ts, one file per adapter per convention)
  • Type check passes (npm run typecheck)
  • Build passes (npm run build)
  • No regressions vs main (before/after diff of full suite)
  • Bundles regenerated (server.bundle.mjs, cli.bundle.mjs, hooks/security.bundle.mjs)
  • README + docs/platform-support.md updated
  • Routing instructions file added (configs/mistral-vibe/AGENTS.md)

Add support for Mistral AI's official coding CLI, Mistral Vibe
(https://github.com/mistralai/mistral-vibe, package: mistral-vibe on PyPI,
command: vibe).

## What's added

- New `MistralVibeAdapter` (`src/adapters/mistral-vibe/`) implementing the
  `HookAdapter` contract for Vibe's JSON stdin/stdout hook paradigm over
  TOML-declared hooks (`~/.vibe/hooks.toml`).
- Hook scripts (`hooks/mistral-vibe/{pretooluse,posttooluse}.mjs`) that
  translate between Vibe's wire format and context-mode's routing/session
  event pipelines.
- Vibe formatter added to `hooks/core/formatters.mjs` and namer added to
  `hooks/core/tool-naming.mjs`.
- Platform registration in `types.ts`, `detect.ts` (env-var, config-dir,
  session-dir, and getAdapter switch), `client-map.ts`, `cli.ts` (hook
  dispatcher), and `platform-detect.mjs` (hook-side mirror).
- Routing instructions at `configs/mistral-vibe/AGENTS.md` (Vibe's default
  instruction file).
- Adapter test suite (`tests/adapters/mistral-vibe.test.ts`, 49 tests).
- README + `docs/platform-support.md` sections.

## Design notes

- **Paradigm**: json-stdio over TOML `[[hooks]]` array tables. Same
  subprocess-with-JSON-payload model as Claude Code / Codex / Kimi, but
  hooks live in a sibling `hooks.toml` distinct from `config.toml`.
- **Capabilities**: `preToolUse` and `postToolUse` true;
  `canModifyArgs` true (via `hook_specific_output.tool_input`);
  `canModifyOutput`, `preCompact`, `sessionStart`, and
  `canInjectSessionContext` false — Vibe exposes only `pre_tool`,
  `post_tool`, and `post_agent`, and `post_tool`'s
  `additional_context` is append-only.
- **Session continuity**: no PreCompact/SessionStart hook available. The
  routing block in AGENTS.md provides model-side memory queries as the
  compaction-recovery workaround.
- **Detection**: relies on `$VIBE_HOME` env var + `~/.vibe/` directory
  presence, NOT MCP `clientInfo.name`. Vibe uses the MCP SDK default
  `Implementation(name="mcp", version="0.1.0")` because it does not
  pass `client_info` to `ClientSession` — that name is too generic
  to safely map to any platform. Client-map entries are placeholders that
  will match if Vibe ever ships a proper client_info.
- **Coexistence with rtk**: both context-mode and rtk register `pre_tool
  bash` hooks. Vibe runs hooks in TOML declaration order; users should
  keep `context-mode-pretool` first so redirected commands never reach
  rtk. The two coexist cleanly; context-mode's redirect is a no-op
  passthrough when it does not apply.
- **VIBE_HOME env var** is registered with `detect: false` so an
  unrelated shell with the var set does not misclassify a non-Vibe host.

## Testing

- 49 new adapter tests all pass
- Baseline (main): 4688/4742 pass, 25 pre-existing failures
- With PR: 4737/4791 pass, 25 pre-existing failures
- Delta: +49 tests, zero regressions (all pre-existing failures are
  git-config / test-env issues unrelated to this change; verified by
  before/after diff)
- Fix to `tests/util/project-dir-matrix.test.ts` adds `"mistral-vibe"`
  to the platform sanity list (matches the pattern documented in the
  existing comment: "When adding a new adapter, append it here").
- Verified end-to-end with a live `vibe --output json` session:
  `context-mode-pretool` and `context-mode-posttool` hooks fire, MCP
  server reachable, `context-mode_ctx_stats` tool responds.

## References

- Vibe hook docs: https://docs.mistral.ai/vibe/code/cli/hooks
- Vibe MCP docs: https://docs.mistral.ai/vibe/code/cli/mcp-servers
- Upstream hook schema: vibe/core/hooks/models.py in mistralai/mistral-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.

1 participant