feat: add MCP collaborative review and human suggesting - #854
Open
shanelindsay wants to merge 22 commits into
Open
feat: add MCP collaborative review and human suggesting#854shanelindsay wants to merge 22 commits into
shanelindsay wants to merge 22 commits into
Conversation
Contributor
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
There was a problem hiding this comment.
Pull request overview
Adds a durable, document-scoped collaborative review lifecycle for MCP-driven and human “Suggesting” edits in Prose, including trusted attribution, suggestion/comment history, and new MCP tools for listing/feedback/revision/decisions.
Changes:
- Introduces durable review lifecycle primitives (review events, suggestion history, attribution + document identity verification) and exposes new MCP review tools.
- Adds local Human Suggesting mode (inline insert/delete/replace suggestions) plus review display modes (all/insertions/simple/original/final).
- Expands Activity/Quick Review surfaces and adds focused Electron E2E coverage for MCP tracked changes + attribution.
Reviewed changes
Copilot reviewed 57 out of 57 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/shared/tools/types.ts | Adds ToolOrigin + durable review attribution/execution context types. |
| src/shared/tools/schemas/review.ts | Adds MCP review collaboration tool schemas (list/feedback/revise/decide/events/status). |
| src/shared/tools/schemas/editor.ts | Adds MCP editor schemas for insert_after and suggest_delete. |
| src/shared/tools/schemas/document.ts | Adds reopen_comment tool schema. |
| src/shared/tools/registry.ts | Registers review tools; expands MCP allowlist and adds isToolExposedViaMCP. |
| src/shared/tools/mcpClientIdentity.ts | Normalizes MCP client identity and builds trusted MCP attribution labels. |
| src/renderer/types/index.ts | Extends onMcpToolInvoke API to include clientIdentity. |
| src/renderer/stores/reviewStore.ts | Allows setReviewMode to accept an initial suggestion index. |
| src/renderer/stores/humanSuggestionModeStore.ts | Adds session-local human editing vs suggesting mode store. |
| src/renderer/stores/editorStore.ts | Adds reviewDisplayMode state + setter for tracked-change display modes. |
| src/renderer/main.tsx | Adds a test seam for comment loading to exercise inactive-load race paths. |
| src/renderer/lib/tools/reviewLifecycle.ts | Adds adapter utilities for attribution, document identity checks, and event/suggestion mapping for MCP. |
| src/renderer/lib/tools/index.ts | Routes new tools; enforces MCP exposure at execution boundary; threads ToolExecutionContext. |
| src/renderer/lib/tools/executors/tabs.ts | Persists suggestion history + review events on tab switch; pre-sets review store document IDs. |
| src/renderer/lib/tools/executors/review.ts | Implements MCP review collaboration executors (list/feedback/revise/decide/events/status). |
| src/renderer/lib/tools/executors/file.ts | Migrates durable review state on Save As; ensures comment loads on open/new. |
| src/renderer/lib/tools/executors/document.ts | Adds documentId/attribution to list/add/resolve/reopen/reply comment tool flows with durability checks. |
| src/renderer/index.css | Adds tracked-change styling + review display mode visibility rules + attribution styling in popover. |
| src/renderer/hooks/useTabs.ts | Saves and migrates review history/events across tab lifecycle operations and renames. |
| src/renderer/hooks/useEditor.ts | Migrates active review state on Save As; ensures review stores align during open/save flows. |
| src/renderer/extensions/review-events.ts | Adds durable append-only review event store persisted to IndexedDB. |
| src/renderer/extensions/comments/store.ts | Adds generation-guarded comment loads and merges to prevent late loads clobbering active state. |
| src/renderer/extensions/comments/extension.ts | Ensures onCommentRemoved fires once per thread even when mark spans multiple nodes. |
| src/renderer/extensions/ai-suggestions/types.ts | Adds deletion type + durable lifecycle record/feedback types + richer provenance fields. |
| src/renderer/extensions/ai-suggestions/store.ts | Adds durable suggestion history + feedback/decision/supersession recording and persistence. |
| src/renderer/extensions/ai-suggestions/presentation.ts | Centralizes “You/MCP/Model” attribution label + explanation handling for UI surfaces. |
| src/renderer/extensions/ai-suggestions/index.ts | Re-exports AISuggestion via human extension; exports extract-based suggestion readers. |
| src/renderer/extensions/ai-suggestions/humanSuggestionShared.ts | Shared helpers for human-inline suggestion mark attrs, range detection, and record queuing. |
| src/renderer/extensions/ai-suggestions/humanSuggestionCommands.ts | Adds accept/reject/restore/revise helpers for human-inline suggestions. |
| src/renderer/extensions/ai-suggestions/humanSuggestionCapture.ts | Adds ProseMirror plugin to capture typing/deletion/paste/cut into human-inline suggestions. |
| src/renderer/extensions/ai-suggestions/humanExtension.ts | Wraps AISuggestion commands to support human-inline behavior transparently. |
| src/renderer/extensions/ai-suggestions/extract.ts | Adds robust grouping extraction of live suggestion marks by ID across multiple nodes. |
| src/renderer/components/review/SideBySideDiffPanel.tsx | Displays suggestion attribution + normalized explanation in side-by-side review. |
| src/renderer/components/review/QuickReviewPanel.tsx | Improves keyboard shortcut gating for editable fields; shows suggestion attribution and type badges. |
| src/renderer/components/layout/Toolbar.tsx | Replaces annotation toggle with ReviewDisplayControl; updates toolbar action label. |
| src/renderer/components/layout/App.tsx | Threads trusted MCP execution context (attribution + expectedDocumentId) through executeTool. |
| src/renderer/components/editor/ReviewDisplayControl.tsx | Adds UI control for human suggesting toggle + review display mode selector. |
| src/renderer/components/editor/Editor.tsx | Records durable comment/suggestion events; adds review display class; improves suggestion restore clearing logic. |
| src/renderer/components/editor/AIEditsHistoryPanel.tsx | Extends Activity feed to include durable suggestion history with feedback and “open in review” behavior. |
| src/renderer/components/chat/ChatPanel.tsx | Scopes Activity badge/filter counts to current document and includes durable suggestion history. |
| src/renderer/components/AISuggestionPopover.tsx | Displays suggestion attribution and normalized explanation in the inline popover. |
| src/preload/index.ts | Passes normalized MCP client identity through IPC to renderer callback. |
| src/mcp-stdio/index.ts | Enforces MCP allowlist on direct calls; forwards trusted clientIdentity; honors PROSE_USER_DATA_DIR. |
| src/main/mcp/socket-server.ts | Lazily resolves socket location; enforces MCP allowlist; forwards normalized client identity. |
| src/main/mcp/http-server.ts | Enforces MCP allowlist for tools/call without needing prior tools/list. |
| src/main/mcp/bridge.ts | Passes normalized client identity to renderer for tool invocations. |
| src/main/index.ts | Makes remote debugging port configurable/disable-able; threads clientIdentity through MCP socket tool calls. |
| README.md | Updates MCP documentation for broader client compatibility + expanded tool list. |
| e2e/electron.mcp-tracked-changes.spec.ts | Adds Electron E2E coverage for MCP insert/delete/display-mode behavior and durability. |
| e2e/electron.mcp-attribution.spec.ts | Adds tests for MCP client identity normalization and attribution safety. |
| docs/issues/831/human-suggesting-qa.md | Adds QA handoff checklist and manual verification plan for human suggesting + MCP flows. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+163
to
+174
| const event = latestReviewEvent(documentId, 'suggestion', args.id, 'suggestion_feedback') | ||
| if (!event) { | ||
| return toolError('Suggestion feedback was applied but its lifecycle event was not recorded', 'LIFECYCLE_EVENT_MISSING') | ||
| } | ||
| await awaitReviewDurability() | ||
| const afterDurabilityError = verifyExpectedDocumentId(context, documentId) | ||
| if (afterDurabilityError) return afterDurabilityError | ||
| const feedbackAt = typeof event.metadata?.feedbackAt === 'number' | ||
| ? event.metadata.feedbackAt | ||
| : event.createdAt | ||
| const feedbackId = `feedback-${args.id}-${feedbackAt}` | ||
|
|
Comment on lines
489
to
492
| /** | ||
| * add_comment - Add a comment mark to a node or explicit range. | ||
| * The comment is tagged with author 'claude'. | ||
| */ |
Comment on lines
411
to
420
| { | ||
| id: 'annotations', | ||
| label: annotationsVisible ? 'Hide AI annotations' : 'Show AI annotations', | ||
| label: `Review display: ${reviewDisplayModeLabel(reviewDisplayMode)}`, | ||
| icon: <Eye />, | ||
| onSelect: toggleAnnotationsVisible, | ||
| active: annotationsVisible, | ||
| onSelect: () => {}, | ||
| active: true, | ||
| renderBar: (key) => ( | ||
| <Tooltip key={key}> | ||
| <TooltipTrigger asChild> | ||
| <Button | ||
| variant="ghost" | ||
| size="icon" | ||
| onClick={toggleAnnotationsVisible} | ||
| aria-label={annotationsVisible ? 'Hide AI annotations' : 'Show AI annotations'} | ||
| aria-pressed={annotationsVisible} | ||
| className={annotationsVisible ? 'bg-accent text-accent-foreground' : 'text-muted-foreground'} | ||
| > | ||
| {annotationsVisible ? ( | ||
| <Eye className="h-4 w-4" /> | ||
| ) : ( | ||
| <EyeOff className="h-4 w-4" /> | ||
| )} | ||
| </Button> | ||
| </TooltipTrigger> | ||
| <TooltipContent>{annotationsVisible ? 'Hide' : 'Show'} AI annotations</TooltipContent> | ||
| </Tooltip> | ||
| <ReviewDisplayControl key={key} /> | ||
| ), | ||
| }, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Prose’s built-in AI workflow is tied to configured providers and API keys. MCP enables model-agnostic collaboration using subscription-backed models and external agents while keeping review decisions in Prose.
What changed
Validation
typecheck:e2e: the same six pre-existing repository errors remain; this branch introduces no additional errors.Closes #831