feat(agents): add MiMo Code provider#2743
Conversation
…mpl-fmg15 # Conflicts: # packages/core/src/agents/plugins/helpers/mcp.test.ts
Greptile SummaryThis PR adds MiMo Code (Xiaomi's OpenCode-based CLI agent) as a new provider, following the established pattern for OpenCode-fork integrations. The implementation is thorough and well-tested, covering the plugin definition, MCP adapter, hook plugin, icon, and shared registry entries.
Confidence Score: 4/5Safe to merge with a minor fix to the embedded plugin file before the hook session-ID path is relied upon in production. The implementation is clean and consistent throughout — every TypeScript file correctly mirrors the OpenCode pattern. The one concrete defect is in the embedded JS plugin string: getMimoSessionId uses isNonEmptyString instead of the ses-prefix check, so any non-empty string property on a session event would be forwarded to emdash and stored. The TypeScript validateSessionId acts as a downstream guard but cannot prevent the wrong value from being persisted. All other parts of the change are well-structured and covered by tests. packages/plugins/src/agents/impl/mimocode/plugin-file.ts — the embedded plugin string needs the ses-prefix guard added to getMimoSessionId.
|
| Filename | Overview |
|---|---|
| packages/plugins/src/agents/impl/mimocode/plugin-file.ts | Embedded JS plugin for MiMo Code hooks — getMimoSessionId uses a looser isNonEmptyString check instead of the ses-prefix validation present in the equivalent OpenCode plugin, creating a mismatch with the documented session-ID contract. |
| packages/plugins/src/agents/impl/mimocode/index.ts | New MiMo Code plugin definition — closely mirrors the OpenCode plugin, correctly declares capabilities, uses validateSessionId with ses-prefix guard, and wires up mimocodeMcpAdapter. |
| packages/core/src/agents/plugins/helpers/mcp.ts | Adds mimocodeMcpAdapter as a thin wrapper around opencodeMcpAdapter with MiMo-specific config paths — correct and minimal. |
| apps/emdash-desktop/src/shared/core/agents/agent-provider-registry.ts | Registers MiMo Code in the shared provider list with correct metadata, flags, and icon reference. |
| packages/plugins/src/agents/impl/mimocode/icon.ts | Defines the SVG icon asset with fill=currentColor for theme adaptation; single light variant, consistent with similar providers. |
| packages/plugins/src/agents/impl/mimocode/index.test.ts | Good test coverage for fresh prompt, auto-approve env, resume with native session ID, and UUID-seed fallback to --continue. |
| packages/core/src/agents/plugins/helpers/mcp.test.ts | Tests cover both write (primary config path) and read (both legacy paths) for the MiMo adapter, following existing test patterns. |
| packages/plugins/src/agents/registry.ts | Imports and registers the MiMo Code provider in alphabetical order, consistent with the rest of the registry. |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant E as Emdash
participant M as MiMo CLI (mimo)
participant P as emdash-notifications plugin
E->>M: spawn `mimo --prompt "..."` + MIMOCODE_PERMISSION env
M->>P: "fires session.* events"
P->>P: getMimoSessionId(event)
P-->>E: "POST /hook {type:'session', sessionId}"
E->>E: store providerSessionId
Note over E: validateSessionId checks startsWith('ses')
E->>M: resume: `mimo --session ses_abc123`
M->>P: fires session.idle
P-->>E: "POST /hook {type:'notification', ...}"
E->>M: resume (no native ID): `mimo --continue`
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant E as Emdash
participant M as MiMo CLI (mimo)
participant P as emdash-notifications plugin
E->>M: spawn `mimo --prompt "..."` + MIMOCODE_PERMISSION env
M->>P: "fires session.* events"
P->>P: getMimoSessionId(event)
P-->>E: "POST /hook {type:'session', sessionId}"
E->>E: store providerSessionId
Note over E: validateSessionId checks startsWith('ses')
E->>M: resume: `mimo --session ses_abc123`
M->>P: fires session.idle
P-->>E: "POST /hook {type:'notification', ...}"
E->>M: resume (no native ID): `mimo --continue`
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
packages/plugins/src/agents/impl/mimocode/plugin-file.ts:40-55
**Missing `ses`-prefix guard on session ID extraction**
`getMimoSessionId` uses `isNonEmptyString` rather than the OpenCode-equivalent guard that requires the value to start with `'ses'`. The `index.ts` comment and `validateSessionId` both document that MiMo Code session IDs follow `^ses.*`, but the plugin has no such check. Any non-empty string in `event.properties.info.id` or `event.properties.sessionID` on a `session.*` event would be forwarded to emdash and stored as `providerSessionId`. If that value doesn't satisfy `startsWith('ses')`, the TypeScript-side guard will silently reject it at resume time and fall back to `--continue`, discarding the native session. Aligning this with the OpenCode pattern (`value.trim().startsWith('ses')`) keeps the plugin consistent with its own contract.
Reviews (1): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile
Description
Screenshot/Recording (if applicable)
https://cap.link/r43hk7wz6bkz9x3
Checklist
messages and, when possible, the PR title