Skip to content

fix(mcp): preserve Muse-saved entries during reconciliation - #1345

Merged
SaulMoro merged 1 commit into
Tencent:mainfrom
nateEc:fix/1221-muse-preserve-entries
Oct 23, 2026
Merged

SaulMoro merged 1 commit into
Tencent:mainfrom
nateEc:fix/1221-muse-preserve-entries

Conversation

@nateEc

@nateEc nateEc commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

After #1319, applyJson normalized Muse's saved MCP map in place and then wrote it. Adding, updating or removing one team server could therefore add type: stdio to a personal server or an unchanged managed server.

Use a separate comparison view for normalization and ownership checks. Apply changes to the original document, retaining its saved entry shapes and original rollback snapshot.

Validation:

  • RED: all three add/update/remove preservation regressions failed on main.
  • npx vitest run src/__tests__/muse.test.ts: 33 passed.
  • npm run build and npx vitest run --config vitest.e2e.config.ts src/__tests__/e2e/muse-support.test.ts: 7 passed, including a real built-CLI writing pull followed by uninstall that leaves the personal server unchanged.
  • npx tsc --noEmit, npm run lint, and git diff --check: passed.

State review: readJsonDoc reads settings, ownership/adoption/history checks consume the comparison map, and writeJsonDoc writes the original map with only actual desired-set changes. previousData remains the original rollback snapshot. Installed-entry/doctor normalization stays read-only. Bilingual MCP guidance and troubleshooting skill data are updated.

The saved settings rewrite is a deterministic fixture; no live Muse process was available locally.

Broader regression: npx vitest run --maxWorkers=6 in a frozen integration worktree containing the five changes finished with 500 files passed, 12,285 tests passed, 36 skipped, 2 failed. Both failures are the pre-existing submodule-checkout.test.ts empty legacy hook-file cases; a clean 83f6d1db worktree independently reproduced 24 passed / the same 2 failed. This is an integration-suite record, not a claim that the baseline is fully green.

Refs #1221. One independently reviewable defect from the issue; the audit/issue remains open for its other items.

- Normalize Muse's inferred stdio type in a separate comparison map, leaving the document passed to atomic writes in the member's saved form.
- Use the comparison view for ownership, adoption, removal and historical matching while applying only actual desired-set changes to stored entries; retain the original rollback snapshot.
- Add regressions for writing pulls that add, update or remove team servers, preserving personal entries and unchanged managed entries; document the behavior in both guides and troubleshooting skill data.
- Verify 33 Muse unit tests and all 7 built-CLI Muse E2E cases, including a writing pull followed by uninstall, plus TypeScript and lint.

Refs: Tencent#1221
@github-actions

Copy link
Copy Markdown

No findings in the specified PR diff.

The comparison map separates Muse normalization from saved entries, while preserving the original rollback snapshot. The changes and regression tests are focused on the stated defect.

The PR description satisfies the testing requirement: it records a build and representative real-CLI pull/uninstall verification. It also explicitly documents the two broader-suite failures reproduced on the baseline.

Review was read-only; I did not run, build, or install PR code.

@SaulMoro SaulMoro left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This was generated by AI during triage.

@nateEc Thanks, approving. This closes the write-back half of the #1221 Muse item. #1346 covers the key-order half.

We built this head, its merge-base 83f6d1db and main 54622c3a. We ran a real pull that writes settings.json, adding a team server, while Muse-saved entries without type were present.

  • base and main: the pull adds "type": "stdio" to the personal and local entries.
  • this head: they stay byte-for-byte unchanged, and only the new extra entry gets type: stdio, as a teamai write should.

Uninstall still removes the unchanged entries. The three new unit cases fail on base and pass here, muse.test.ts (33), the MCP unit set (536) and muse-support (7/7) pass, and tsc, lint and CI pass.

Suggestions:

  • [P2 non-blocking] #1346 conflicts with this PR in four files. Whichever of the two lands second has to keep the normalized view in #1346's legacy fallback: judge(name, comparable.servers[name], previous.hash) rather than doc.servers[name]. We built the two together. Without that line, an unchanged legacy stdio server is kept on uninstall and a muse.test.ts legacy case fails, though the e2e tests pass. With it, everything passes. Landing this one first keeps the change on #1346's side.
  • [P2 non-blocking] The sharing.md (EN and zh-CN) and troubleshooting edits describe an internal comparison a user doesn't act on. AGENTS.md asks to leave docs alone for such a fix, so we'd drop them.
  • [P3 nit] comparable.servers[name] ?? entry in the trailing stale-entry loop can't fall back, so ?? entry is dead code.

CI review: it reported no findings and accepted the testing record. We agree on the code. The doc point and the interaction with #1346 are our additions.

@SaulMoro
SaulMoro merged commit 59f2d88 into Tencent:main Oct 23, 2026
18 checks passed
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