Skip to content

Merge upstream/main (a914a30, 19 commits) — en attente du fix upstream, NE PAS MERGER - #57

Merged
tournierjc merged 24 commits into
mainfrom
merge/upstream-a914a30
Sep 23, 2026
Merged

tournierjc merged 24 commits into
mainfrom
merge/upstream-a914a30

Conversation

@tournierjc

Copy link
Copy Markdown
Collaborator

Merge upstream/main a914a30 → fork (19 commits)

⚠️ EN ATTENTE DU FIX UPSTREAM — NE PAS MERGER (décision JC 20/09 : la PR reste ouverte jusqu'au fix upstream telemetry).

Commits upstream intégrés (19, ae65651..a914a30)

Doublons

Aucun : 0 commit du lot déjà couvert par une PR fork (vérifié par ancestor-check 19/19 absents de main).

Criblage telemetry

  • Aucun commit bloqué. URLs ajoutées = fixtures/homepages uniquement (relay.example, eslint homepages, docs/theme-config.md relatif) — aucun host sortant réel.
  • createConfiguredTuiBusinessTelemetry (usine telemetry amont, HEAD du conflit launcher.ts) rejetée ; businessEventTracker/trackChatSend non intégrés (app.ts) ; docs/telemetry.md reste absent ; incident-reporter.ts + son test : UD → delete (fork).

Conflits (16 fichiers) et résolutions

Gates

  • AVANT (fork main 02d51ce) : check_gates.sh 10/10 verts (typecheck, copilot-connector, provider-presets, provider-application, session-tabs, session-cost, provider-manager, command/feature-flow, identity kinetick-code 0.5.2, egress-guard).
  • APRÈS (branche merge/upstream-a914a30) : 10/10 verts, smoke 20 pass / 0 fail, test:byok 3/3, build 6377 files OK, source-inventory exit 0.

Frontières fork préservées

  • Telemetry amont hors arbre (docs/telemetry.md, analytics/, incident-reporter) ; egress guard default-deny intact (diff vide vs main) ; identité kinetick-code 0.5.2 vérifiée par gate.

hetaoBackend and others added 24 commits September 22, 2026 16:35
* feat(tui): add selectable themes and custom theme files

MCode TUI colors are now driven by named themes, each shipping a dark
and a light palette. `/theme` opens a panel with live preview so users
can switch themes and lock light/dark on top of terminal detection.

Custom theme files under `tui/themes/*.json` support partial overrides,
color aliases and syntax palettes, and hot reload so editing a theme in
use takes effect without restarting.

The selected theme persists in `tui/tui-settings.json` alongside
`tuiMode`; unrecognized values fall back to the default theme instead of
blocking startup.

Assisted-by: mavis reason:port-theme-system

* test: register theme system tests and source inventory

The public source gate requires every first-party test to be listed in
test/vitest-suites.json and every shipped source path to be recorded in
release/public-source.json. Register the new theme system tests and the
11 files this change adds.

Assisted-by: mavis reason:register-theme-tests
* perf(edit): bound the post-edit diff and unified patch

`edit` computed its display diff and its unified patch with unbounded
Myers, which costs O((N+M)*D) in the edit-script length D. A whole-file
rewrite therefore scaled quadratically in the number of changed lines:
rewriting every line of a 20 000-line file blocked the tool for over two
minutes and produced a multi-megabyte patch that no renderer displays.
The sibling `write` path already caps the same work in
`packages/agent-tools/src/shared/write-capture.ts`; `edit` had no cap.

Pass jsdiff's `maxEditLength` (1000 edits) and `timeout` (5 s) to
`diffLines` and `createTwoFilesPatch`. `maxEditLength` is the primary
bound because it is deterministic and therefore unit-testable; `timeout`
only backstops slow machines. When a bound trips, `details.diff` carries
a one-line notice so every renderer still has something to show,
`details.patch` is omitted, and the new `details.diffOmitted` names the
reason. The unified patch is skipped once the display diff was abandoned
rather than repeating a second Myers run that aborts on the same bound.
The file is written before any diff runs, so a dropped diff never
changes what lands on disk.

Measured end to end through `createEditTool` on a 20 000-line whole-file
rewrite, three runs each on the same machine: 120 s / 138 s / 139 s
before, 60 ms / 60 ms / 58 ms after.

Assisted-by: minimax-code reason:bound-edit-diff-cost

* fix(tui): render an omitted edit diff as a summary block

When the edit tool hits its diff bounds it replaces the diff body with a
one-line notice, so the body carries no `+`/`-` lines. Both preview
consumers misread that notice as a real diff:

- The TUI counted changed lines from the body and rendered
  `subject.ts · +0 -0 · Applied` for a 20k-line rewrite.
- The ACP projector ran the notice through `parseUnifiedDiff`, emitting a
  diff block with `oldText === newText === "(diff omitted: ...)"`, which a
  client renders as "no changes".

Read `details.diffOmitted` alongside `details.diff` and emit the existing
summary block instead, which renders as a header plus the notice and needs
no line counts. `timeout` maps to `unavailable`, bounds hits to `too-large`.

E2E: PASS (tmux TUI against dist/cli.js, 20000-line replace_all edit:
header is `subject.ts · Applied` + `(diff omitted: more than 1000 lines
changed)`; a 1-line edit still renders `+1 -1 · Applied`)

* fix(agent-tools): keep Compatible hooks working when the edit patch is bounded out

Bounding the post-edit diff drops `details.patch` on exactly the edits
the bound targets, and `withCompatibleEditToolResponse` returned the
result untouched in that case. The Compatible PostToolUse payload then
carried no `tool_response`, so `needsPostToolAdapter` found no usable
CLAUDE handler and the runner rejected the hook with
HOOK_INVALID_INPUT — every Compatible PostToolUse hook was silently
skipped on large edits that used to run fine. There is no fallback for
`edit` in `buildCompatiblePostToolResponse`, unlike bash, read and mcp.

Synthesize the structured patch instead of reparsing one that does not
exist: a bounded-out edit is by definition a wholesale rewrite, so emit
a single hunk that removes every old line and adds every new one. This
costs no Myers run, keeps the payload the same order as the
`originalFile` already in it, and stays a correct — if imprecise —
description of what landed on disk. The `\ No newline at end of file`
marker is reproduced on whichever side lacks the trailing newline, in
jsdiff's position.

`EditCapture` now also carries the written content, and BOM stripping is
shared between the two sides so the synthesized hunk matches what
jsdiff would have produced.

Assisted-by: minimax-code reason:bound-edit-diff-cost

* fix(edit): report why the unified patch was omitted

The unified patch is a second, independently timed Myers run over the
same input as the display diff. When only that run ran out of time,
`details` held a diff, no patch, and no `diffOmitted`, so a consumer
could not tell an omitted patch apart from a tool that never produces
one.

Add `details.patchOmitted`: it mirrors `diffOmitted` when the display
diff was abandoned, and reports `timeout` when only the patch was, so
`details.patch` is absent exactly when `patchOmitted` is set. jsdiff
routes `createTwoFilesPatch` through the same bounded `diffLines`, so
`maxEditLength` is deterministic across both runs and can never trip for
the patch alone; only its separately measured wall clock can.
`diffOmitted` keeps its meaning and is unchanged.

The patch-only timeout is not unit-testable — it needs the two runs to
land on opposite sides of a 5 s wall clock, which no deterministic input
can force — so the tests pin the invariant on both reachable paths
instead.

Assisted-by: minimax-code reason:bound-edit-diff-cost

* fix(edit): raise the diff bound so ordinary rewrites keep their diff

`maxEditLength` bounds D, the length of the Myers edit script, not the
number of changed lines: replacing a line costs one deletion plus one
insertion. A bound of 1000 therefore gave up on any full rewrite past
500 lines, and a reported 501-line whole-file replacement lost its diff
even though the whole tool call, diff included, finishes in under 55 ms.
That is well inside what the tool should still render.

Raise the bound to 2000, which admits a full rewrite of any file up to
1000 lines. Measured end to end through `createEditTool`, three runs
each on the same machine: 53 / 49 / 47 ms for a 501-line rewrite,
177 / 173 / 177 ms for 1000 lines, and 200 / 192 / 193 ms for a
20 000-line rewrite that still gives up — against 167 620 / 173 523 /
167 547 ms unbounded, with peak heap dropping from 47-60 MB to
14-15 MB. Doubling the bound roughly doubles the worst case the bound
itself admits, which stays near 200 ms.

Also correct the notice the bound emits. It read "more than N lines
changed", which misreports a rewrite by a factor of two; D is exactly
the number of added plus removed lines, so say that instead.

Assisted-by: minimax-code reason:bound-edit-diff-cost

* fix(agent-tools): send an empty structured patch when the edit patch is bounded out

Synthesizing a whole-file hunk kept Compatible PostToolUse handlers
selectable when the bound dropped `details.patch`, but pushed the hook
payload past the runner's 1 MiB input limit on exactly the large files
the bound targets. A 20 000-line file with 1001 changed lines serialized
to 1 679 234 B and failed `serializeHookInput`, so the handler still
never ran — it now failed one step later than before. Trimming the
common prefix and suffix does not fix that either: the same shape still
reaches 1 154 543 B on a 960 KB file.

`structuredPatch` is a required array in the Compatible file-edit output
schema, and the upstream tool already sends `[]` when its own diff times
out, so the empty array is that schema's own way to say "no diff
information". It keeps the handler selectable, keeps `edit` renamed to
`Edit` for matchers, and passes the write-back `hasCompatibleJsonShape`
check, which compares array-ness only and so still accepts a hook that
returns real hunks. The same payload now serializes to 563 600 B.

`EditCapture.updatedFile` existed only to feed the synthesized hunk and
goes away with it, restoring the capture to its previous shape. A
malformed `details.patch` now also degrades to `[]` instead of dropping
the whole compatible response, which is strictly better: the handler
runs rather than being skipped with HOOK_INVALID_INPUT.

This does not make every hook payload fit. The response separately
carries `originalFile`, `oldString` and `newString` in full, so a
whole-file rewrite of a large file still exceeds the limit on those
fields alone, both before and after this change. That bound predates
this branch and is left alone.

Also correct the stale timings in the test header, which predated the
remeasurement at the current bound.

Assisted-by: minimax-code reason:bound-edit-diff-cost
An Anthropic-compatible relay that routes prompt-cache hits per session had
no documented way to learn the session identity. The request builder forwards
metadata.user_id only when a caller sets metadata explicitly, because it is an
abuse-detection and attribution field rather than a cache key, so nothing in
the public documentation explained how to preserve session identity instead.

Document the supported sendSessionAffinityHeaders compat override for custom
providers, and pin the resulting wire-level request: no session identity
without the override, x-session-affinity once a provider entry opts in, and no
session header when the turn runs without prompt caching.

Closes MiniMax-AI#318
…-AI#324)

* docs(tui): design follow-tail preservation

* docs(tui): add follow-tail implementation plan

* fix(tui): preserve detached transcript position

* fix(tui): re-arm follow-tail on explicit navigation

* test(tui): cover follow-tail intent boundaries

* fix(tui): re-arm follow-tail for queued messages

* fix(tui): ignore stale queue admissions
* fix(tui): restore early-aborted prompt to composer

* fix(tui): preserve restored submission edits and metadata
* fix(tui): clear previous run duration on new turn

* fix(tui): dismiss stale duration when a message appears
Render the projected submission synchronously so the prior interrupted footer is erased before input returns. Queue the normal input render before dispatch so a synchronous render coalesces instead of doing a second pass.
)

* feat(tui): select plugins with durable identity mentions

* test(tui): update plugin mention discovery hints

* fix(tui): preserve plugin bindings across draft and message edits

* fix(tui): retain unique plugin labels across multiple external edits

* fix: reconcile plugin mention display and simplify completion rows

* fix(tui): reconcile theme edits missed during watcher startup
# Conflicts:
#	docs/tui-capabilities.md
#	package.json
#	packages/tui/package.json
#	packages/tui/src/observability/incident-reporter.ts
#	packages/tui/src/tui/app.ts
#	packages/tui/src/tui/controller/run/active-run-flow.ts
#	packages/tui/src/tui/launcher.ts
#	packages/tui/src/tui/theme/controller.ts
#	packages/tui/src/tui/theme/palettes.ts
#	packages/tui/src/tui/theme/runtime.ts
#	packages/tui/test/unit/incident-reporter-privacy.test.ts
#	packages/tui/test/unit/tui-chat-controller.test.ts
#	packages/tui/test/unit/tui-engine-local-deltas.test.ts
#	release/public-source.json
#	test/source-sync.test.mjs
#	test/vitest-suites.json
…ollow-up)

- auth/application.ts: drop the no-useless-catch try/catch wrapper in login()
- transcript/usage-visualization.ts, update/application.ts: prefer-template
- update-release.test.ts: prefer-template in fixture URLs
- package-identity.test.ts: import the scripts/lib/package-identity.mjs via
  import.meta.resolve so the cross-package reference satisfies
  import/no-relative-packages while keeping the vitest resolution path
…identity

- tui-app.test.ts: /usage placeholder assertion 'Ask Mcode…' -> 'Ask Kcode…'
- theme tests (palettes/custom-themes/runtime): MINIMAX_CODE_DARK/LIGHT_THEME
  and MINIMAX_CODE_THEME_CONTRAST_POLICY renamed to the KCODE_* exports the
  fork's theme/palettes.ts ships; theme-contrast helper gains the
  KCODE_THEME_CONTRAST_POLICY alias with the same palette roles
@tournierjc
tournierjc merged commit 31cd57e into main Sep 23, 2026
26 of 27 checks passed
@tournierjc
tournierjc deleted the merge/upstream-a914a30 branch September 23, 2026 23:03
tournierjc pushed a commit that referenced this pull request Oct 2, 2026
…low mock

The duplicate key dates from the #55/#57 merge on origin/main (5bba9c7): both
sides added the same mock key. vitest transforms tolerate it; ESLint does not.
tournierjc added a commit that referenced this pull request Oct 3, 2026
…r, on 0.6.0/0.6.1 sync) (#110)

* fix: remove forced branching from bash guidance (MiniMax-AI#358)

Co-authored-by: minimax <adhere@minimaxi.com>

* feat: sync reviewed 0.5.5 runtime improvements (MiniMax-AI#367)

Preserve public privacy defaults and distribution boundaries while porting compaction, Bash timeout, memory output and update-proxy improvements. Record selective provenance without advancing the full source baseline.

Assisted-by: codex-cli reason:public-source-sync-0.5.5

* docs: publish feedback and private security contact channels (MiniMax-AI#360)

* docs: publish feedback and private security contact channels

* docs: correct MiniMax Agent X contact link

* fix(tui): distinguish Bash recaps and import models during onboarding (MiniMax-AI#369)

* fix: measure token speed over model generation time (MiniMax-AI#373)

* chore: bump version to 0.5.6 (MiniMax-AI#374)

* feat(config): add M3.1 Flash Preview to the fallback catalog (MiniMax-AI#375)

Include context window and effort controls in the first-run catalog while preserving existing managed snapshots.

Docs-Impact: Existing model selection workflow is unchanged.

Assisted-by: codex-cli reason:m31-flash-fallback-sync

* chore: bump version to 0.5.7 (MiniMax-AI#377)

* chore: bump version to 0.5.7

* test: drain stderr before nonzero Bash fixture exit

* fix(tui): display hook system messages without adding model context (MiniMax-AI#376)

* fix(tui): anchor restored sessions above inherited terminal history (MiniMax-AI#378)

* fix(tui): keep slow terminal output off the input loop (MiniMax-AI#379)

* chore: bump version to 0.5.8 (MiniMax-AI#380)

* feat: cascade explicit session stops to owned background work (MiniMax-AI#381)

Port the reviewed shared runtime behavior while retaining standalone composition. Keep conversation leave separate from explicit stop, suppress canceled task delivery, and track append activations through teardown.


Assisted-by: codex-cli reason:selective-runtime-port
Docs-Impact: document stop and session-leave behavior in docs/tui-capabilities.md

Co-authored-by: chenhao <chenhao@minimaxi.com>

* fix: query structured Windows source volume properties (MiniMax-AI#383)

* feat(examples): add Pocket Pet demo and refresh README onboarding (MiniMax-AI#385)

* feat(examples): add reproducible Pocket Pet demo and refresh onboarding

* feat(examples): polish Pocket Pet interaction and demo

* fix(tui): dismiss stale terminal errors when a new turn starts (MiniMax-AI#388)

* fix(tui): preserve native scrollback during automatic updates (MiniMax-AI#389)

* fix(tui): preserve native scrollback during projection updates

* fix(tui): isolate transient overlays from native scrollback

* fix(tui): stabilize native history and diff overlay frames (MiniMax-AI#390)

* fix(tui): prevent idle transcript replay and diff overlay frames

* fix(tui): retain prompt identity and deferred main-buffer geometry

* test: pin the srt-macos probe PATH and scale the BYOK serial timeout budget (MiniMax-AI#397)

* test(sandbox): pin the probe PATH instead of inheriting the ambient one

The real sandbox-exec probes resolve their command through PATH, so
inheriting the caller's let any wrapper ahead of /bin decide what `rm`
means. On a machine that has run the agent, that is the recoverable-delete
shim MCode installs into agent shells: `rm` resolves to the shim, the shim
execs mavis-trash, the sandbox denies that trash move as a write outside
the policy under test, and a correct allow-probe exits 1. The suite then
reports a sandbox regression where the sandbox behaved correctly.

Pin all three probe environments to the system binaries the probes
actually use, matching the wrapper-argument test above them. This also
drops the unguarded `process.env.PATH` in wrapProfile, which had no
fallback and could hand a real sandbox spawn an undefined PATH.

Fixes MiniMax-AI#394.

* test(byok): scale the serial BYOK budget by platform

The first case is 30+ serial CLI spawns, each booting the whole runtime,
so its wall-clock cost tracks machine speed rather than the transport it
asserts. The flat 90s budget only held with roughly 1.5x headroom on an
idle machine, so a parallel build, a laptop under load, or a shared CI
runner turned a passing transport into a `testTimeoutFailure` that named a
product failure no assertion had actually observed.

Budget it the way smoke.test.mjs already budgets runtime startup: a base
allowance plus a Windows multiplier for slower process spawn. The test is
not slowed down by a larger ceiling; it only stops failing for reasons
unrelated to what it checks.

Fixes MiniMax-AI#395.

* feat: sync MiniMax Code 0.5.9 runtime and TUI changes (MiniMax-AI#398)

TUI
- Report active root-session background tasks as `background=N` in the
  `[V]` build-mode status line. Bash still owned by its foreground tool
  call is excluded, and the count holds at 1 after a turn settles until a
  fresh task list arrives. The documented minimum width is now 102 columns.

Runtime
- The MiniMax API-key route now shares the official model catalog with the
  managed route; the first-run catalog moves to `minimax-model-catalog.ts`
  with unchanged model definitions.
- Apply byte limits to large media and accumulated history for BYOK requests.
- Send the M3 thinking toggle as a thinking setting rather than a generic
  reasoning effort.
- Allow edit and rewind after an interrupt that left only a background
  reminder in canonical history.
- Read less data when listing session files and navigating long histories.
- Measure token output rate from the time events are observed.
- Add `worktreeRefreshBeforeCreate` (default on) to fetch the selected
  upstream before creating a worktree, and exclude nested roots from fork
  worktree fingerprints.
- Add Ghostty to the external editor catalog.
- Enable the Codex OAuth model settings entry by default.

Prompts
- Cron guidance now lives only in tool definitions; the legacy feature
  template is empty. Memory edits use the `memory` tool's `edit` operation.
- Clarify multimodal tool discovery in the mcode-tools reminder.

* chore: release MiniMax Code 0.5.9 (MiniMax-AI#399)

* Revert MiniMax-AI#390 and MiniMax-AI#389 to restore TUI scrollback baseline (MiniMax-AI#396)

* Revert "fix(tui): stabilize native history and diff overlay frames (MiniMax-AI#390)"

This reverts commit 1e136bf.

* Revert "fix(tui): preserve native scrollback during automatic updates (MiniMax-AI#389)"

This reverts commit 9b9c07b.

* fix(tui): sync 0.5.10 prompt and run recovery fixes (MiniMax-AI#410)

* chore: release MiniMax Code 0.5.10 (MiniMax-AI#411)

* fix: include hidden thinking in TPS timing (MiniMax-AI#413)

* fix: include hidden thinking in TPS timing

* docs: note thinking_start in first token timing comment

* test(windows): allow the NTFS source check to exceed the default timeout

---------

Co-authored-by: hetaoBackend <hetao7@pku.edu.cn>

* fix: omit empty tools from OpenAI compaction requests (MiniMax-AI#199)

* fix: omit empty tools on OpenAI compaction requests

* fix: negotiate missing tools with bounded compatibility recovery

* fix: simplify empty tools handling to omit absent definitions

* fix(tui): keep regular-mode history stable during live runs (MiniMax-AI#416)

Regular mode wrote rows into native scrollback as soon as they scrolled
off screen. When such a row later changed (a parallel tool finishing, a
streamed table widening, a list turning loose, a turn growing past the
projection fold, the welcome status badge flipping, or a stopped prompt
gaining its cancelled marker), the renderer cleared scrollback and
replayed the whole session from the welcome logo.

Only final rows now reach native history:

- The transcript reports how many leading rows later updates cannot
  change, including the committed blocks of a streaming Markdown reply.
- The chat layout keeps rows that may still change within one screen
  above the footer, showing their latest rows under a one-line notice
  when they do not fit.
- The regular-mode projection only appends; established turns are not
  re-folded or dropped.
- The welcome banner above a conversation is static; account notices
  that need action appear above the Composer.
- Stopping a run no longer marks its delivered prompt as cancelled; the
  marker stays reserved for prompts returned to the Composer.

To keep long sessions responsive, the transcript drops final rows far
above the screen and the engine rebases its retained state
(takeDiscardedRows) instead of rewriting history.

* feat: sync and release MiniMax Code 0.6.0 (MiniMax-AI#421)

Port the reviewed 0.6.0 runtime and TUI behavior into the standalone
distribution and bump the release version to 0.6.0.

- Allow /retry inside a /btw side conversation to resend its last message.
- Default to MiniMax-M3.1-Flash-Preview when no model has been selected.
- After an accepted Goal completion, keep the Turn open for one final reply
  that summarizes the result and deliverables; blocked proposals still end
  the Turn.
- Do not retry provider safety refusals, including on BYOK, and classify
  them as content_filter; keep Anthropic refusal details in the error.
- Retry TLS record verification failures before output like other
  transient network errors.
- Keep a post-compaction reminder at the tail of a continuation instead of
  aborting the provider call and recompacting on every retry.

* feat: sync and release MiniMax Code 0.6.1 (MiniMax-AI#422)

Allow /doctor and /feedback in a /btw side conversation so a failed side
response can be diagnosed or reported without leaving it. Neither command
mutates the parent or side Session. /quit stays blocked in the side view,
because leaving from there aborts only the side Turn and skips side
Session cleanup.

Bump the root and TUI source versions to 0.6.1.

* test(tui): adopt upstream MiniMax-AI#410 literal-prompt assertion in compact-rail test

Upstream 5683465 (MiniMax-AI#410) changed the 'renders intent and execution as one
compact visual rail' expectation to keep the prompt's ** markers literal
(fork prompt-literal behavior). The three-way merge kept the pre-MiniMax-AI#410
expectation; adopt the MiniMax-AI#410 form.

* fix(config): adopt upstream MiniMax-AI#421 default model MiniMax-M3.1-Flash-Preview

Upstream 9150441 (sync 0.6.0) flipped buildPresetEntry's defaultModel to
minimax/MiniMax-M3.1-Flash-Preview; the three-way merge kept the main side
for config.ts and dropped the flip, breaking the MiniMax-AI#421-pinned
model-selection/management suites. Restore the upstream value.

* fix(tui): keep side-session Esc and main run timer consistent (MiniMax-AI#423)

In a /btw side conversation, an empty Escape no longer arms the
double-Escape /edit shortcut or shows its "Press Esc again to edit"
hint, since /edit is unavailable in side conversations. Escape still
interrupts a live side response.

Switching between the side and main views re-adopted the main Session's
live Turn at the switch time, which reset the Running/Loading timer and
shortened the settled Turn duration. A Turn start ledger now records the
earliest observed start (submission, session.start events including
hidden Sessions, and adoption), and both re-adoption and the activity
line use it.

Bump the root and TUI source versions to 0.6.2.

* fix(tui): adopt upstream MiniMax-AI#423 side-session Esc and turn start ledger

Record the earliest Turn start across side-session switches so the main
run timer and settled duration stay stable, and ignore double-Escape
/edit while a side conversation is open. Fork packages stay kinetick-code
and @mavis/code at 0.6.9, and multi-tab live turn watchers stay in place.

Co-authored-by: tournierjc <tournierjc@users.noreply.github.com>

* test(tui): drop duplicate applyPendingModelSelection key in command-flow mock

The duplicate key dates from the #55/#57 merge on origin/main (5bba9c7): both
sides added the same mock key. vitest transforms tolerate it; ESLint does not.

---------

Co-authored-by: AdhereZ <85055734+AdhereZ@users.noreply.github.com>
Co-authored-by: minimax <adhere@minimaxi.com>
Co-authored-by: DanielWalnut <45447813+hetaoBackend@users.noreply.github.com>
Co-authored-by: AmsZuidas <254873068+amszuidas@users.noreply.github.com>
Co-authored-by: chenhao <chenhao@minimaxi.com>
Co-authored-by: SaladDay <1203511142@qq.com>
Co-authored-by: hetaoBackend <hetao7@pku.edu.cn>
Co-authored-by: hermes-agent <hermes-agent@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: tournierjc <tournierjc@users.noreply.github.com>
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.

4 participants