Skip to content

feat(mcp): add edit_file/append_file for partial writes - #3188

Merged
amirbiron merged 4 commits into
mainfrom
claude/mcp-codekeeper-webapp-ldnzsg
Jul 20, 2026
Merged

feat(mcp): add edit_file/append_file for partial writes#3188
amirbiron merged 4 commits into
mainfrom
claude/mcp-codekeeper-webapp-ldnzsg

Conversation

@amirbiron

@amirbiron amirbiron commented Jul 20, 2026

Copy link
Copy Markdown
Owner

מה נבנה — עריכה חלקית בלי לשלוח את כל הקובץ

שני כלים חדשים, שניהם מאחורי הרשאת write כמו save_file:

1. codekeeper_edit_file — מצא‑והחלף מדויק:

file_name, old_string → new_string, replace_all (ברירת מחדל: false)
  • סמנטיקה זהה לכלי ה‑Edit הנייטיב, אז Claude ישתמש בו טבעי
  • old_string לא נמצא → no_match; מופיע כמה פעמים → ambiguous_match + כמה מופעים + רמז (להאריך את הקטע או replace_all=true); זהים → שגיאה. בשום מקרה של שגיאה לא נשמר כלום

2. codekeeper_append_file — הוספה לסוף:

file_name, content
  • מוסיף שורת‑הפרדה אוטומטית אם הקובץ לא מסתיים ב‑newline (ה‑changelog/יומן שלך תמיד יתחיל בשורה חדשה)

הבטיחות המובנית בשניהם:

  • כל עריכה = גרסה חדשה באותו מסלול append-only — הגרסה שלפני העריכה תמיד ניתנת לשחזור דרך list_versions. עריכה שגויה היא הפיכה
  • שפה, תיאור ותגיות נשמרים מהגרסה הקודמת — עריכה לא מאפסת מטא‑דאטה
  • אותו שער גודל (100KB) כמו בשמירה רגילה

התוצאה בפועל: עדכון סעיף במסמך של 314 שורות = שליחת הקטע הישן + החדש בלבד (עשרות תווים במקום ~6,800). וגם עריכה שנכשלת על הרשאה עולה כמעט כלום.

אומת: 169 טסטים (כולל 18 חדשים), black/flake8 נקיים, doc8 + Sphinx על עמוד התיעוד (האזהרה היחידה בבנייה היא ארטיפקט מקומי של בנייה אינקרמנטלית — לא קשורה לתוכן).

אחרי שתמזג ל‑main ו‑Render יעשה דפלוי — הכלים יופיעו אוטומטית בחיבור הקיים (אין צורך בחיבור מחדש; ה‑scope כבר כולל write). 🚀

Updating one section of a long document required resending the whole
file through codekeeper_save_file. Add two server-side write tools so
the client only sends the changed part:

- codekeeper_edit_file: exact find-and-replace (old_string ->
  new_string, optional replace_all) with native-Edit-tool semantics —
  no_match / ambiguous_match (with occurrence count) / identical-strings
  guards, nothing saved on error.
- codekeeper_append_file: append to the end of an existing file,
  inserting a newline separator when the body doesn't end with one.

Both fetch the latest version, apply the change in-process, and persist
through the same append-only versioned save path (pre-edit version stays
recoverable via list_versions). Language, description and tags are
carried over so an edit never resets metadata; the save_file size gate
applies to the resulting body (extracted as _max_code_size and reused).
Both tools require the write scope, same as save_file.

Tests cover _apply_edit semantics, metadata preservation, size gates,
not-found/empty guards, and tool registration; docs updated (README,
mcp-server.rst, FEATURE doc).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNFuSyshwpRcxozVZEui5K
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@github-actions

Copy link
Copy Markdown

🧯 Dangerous deletes guard report

Policy: see .cursorrules — dangerous deletions are blocked unless wrapped safely.

Summary:

  • Flagged findings (blocking): 0
    0
  • Excluded matches (not blocking): 15
  • Total matches (all files): 129

Flagged findings (file:line:snippet):
(none)

Excluded matches (by path pattern)
./webapp/static/js/md_preview.bundle.js.map:4:  "sourcesContent": ["// Markdown-it plugin to render GitHub-style task lists; see\n//\n// https://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments\n// https://github.com/blog/1825-t … [truncated]
./README.md:842:find . -name "__pycache__" -exec rm -rf {} +
./Dockerfile:42:    rm -rf /var/lib/apt/lists/*
./Dockerfile:121:    rm -rf /var/lib/apt/lists/*
./node_modules/mermaid/dist/mermaid.min.js:1524:`,"getStyles"),c1e=RQe});var h1e={};dr(h1e,{diagram:()=>NQe});var NQe,f1e=N(()=>{"use strict";$ge();a1e();l1e();u1e();NQe={parser:Fge,db:n1e,renderer:o1e,styles:c1e}});var m1e,g1e=N(()=>{"use  … [truncated]
./node_modules/mermaid/dist/mermaid.min.js.map:4:  "sourcesContent": ["/**\n* Default values for dimensions\n*/\nconst defaultIconDimensions = Object.freeze({\n\tleft: 0,\n\ttop: 0,\n\twidth: 16,\n\theight: 16\n});\n/**\n* Default values fo … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.core/chunk-KS23V3DP.mjs.map:4:  "sourcesContent": ["{\n  \"name\": \"mermaid\",\n  \"version\": \"11.12.0\",\n  \"description\": \"Markdown-ish syntax for generating flowcharts, mindmaps, sequence  … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.esm/chunk-2M32CCKP.mjs.map:4:  "sourcesContent": ["{\n  \"name\": \"mermaid\",\n  \"version\": \"11.12.0\",\n  \"description\": \"Markdown-ish syntax for generating flowcharts, mindmaps, sequence d … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.esm.min/chunk-4HFYJGYH.mjs.map:4:  "sourcesContent": ["{\n  \"name\": \"mermaid\",\n  \"version\": \"11.12.0\",\n  \"description\": \"Markdown-ish syntax for generating flowcharts, mindmaps, sequen … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.esm.min/chunk-4HFYJGYH.mjs:1:var r={name:"mermaid",version:"11.12.0",description:"Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graph … [truncated]
./node_modules/mermaid/dist/mermaid.js.map:4:  "sourcesContent": ["/**\n* Default values for dimensions\n*/\nconst defaultIconDimensions = Object.freeze({\n\tleft: 0,\n\ttop: 0,\n\twidth: 16,\n\theight: 16\n});\n/**\n* Default values for tr … [truncated]
./node_modules/katex/src/fonts/Makefile:139:	rm -rf pfa ff otf ttf woff woff2
./node_modules/katex/package.json:153:    "build": "rimraf dist/ && mkdirp dist && cp README.md dist && rollup -c --failAfterWarnings && webpack && node update-sri.js package dist/README.md",
./docs/Makefile:24:	rm -rf $(BUILDDIR)
./docs/DOCUMENTATION_GUIDE.md:453:rm -rf _build

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@amirbiron, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 8 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 14824eb1-89f6-4d93-a540-9ed019a38585

📥 Commits

Reviewing files that changed from the base of the PR and between 6069a81 and cacc2a3.

📒 Files selected for processing (4)
  • CLAUDE.md
  • FEATURE_SUGGESTIONS/FEATURE_MCP_CLAUDE_INTEGRATION.md
  • docs/mcp-server.rst
  • mcp_server/README.md
📝 Walkthrough

Walkthrough

נוספו כלי MCP לעריכה ולהוספת תוכן לקבצים קיימים. ה-handlers מבצעים החלפה מדויקת או append, שומרים גרסה חדשה עם מטא-דאטה, אוכפים הרשאת write ומגבלת גודל, ונוספו בדיקות ותיעוד.

Changes

כלי כתיבת MCP

Layer / File(s) Summary
לוגיקת עריכה והוספה
mcp_server/handlers.py, tests/test_mcp_edit_append.py
נוספו edit_file ו-append_file, טיפול בשגיאות ובמגבלת גודל, שמירת גרסה חדשה ושימור מטא-דאטה; נוספו בדיקות לסמנטיקת ההחלפה, append ותרחישי כשל.
רישום והרשאת כלי MCP
mcp_server/server.py, tests/test_mcp_server_build.py
נרשמו codekeeper_edit_file ו-codekeeper_append_file ככלי כתיבה הדורשים write, והבדיקה עודכנה לרשימת הכלים החדשה.
תיעוד ומיפוי הפיצ'ר
FEATURE_SUGGESTIONS/FEATURE_MCP_CLAUDE_INTEGRATION.md, docs/mcp-server.rst, mcp_server/README.md
התיעוד עודכן לתיאור שלושת כלי הכתיבה, הרשאת write, וסטטוס שלב 3 הכולל save ועריכה או append חלקיים.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Claude
  participant MCPServer
  participant Handlers
  participant Backend
  Claude->>MCPServer: בקשת edit או append
  MCPServer->>MCPServer: require_write
  MCPServer->>Handlers: העברת הבקשה והמשתמש המאומת
  Handlers->>Backend: טעינת הגרסה האחרונה
  Handlers->>Handlers: שינוי התוכן ובדיקת מגבלת הגודל
  Handlers->>Backend: שמירת גרסה חדשה עם מטא-דאטה
  Backend-->>Claude: תוצאת הפעולה
Loading

Possibly related PRs

Poem

ארנב קטן מצא מחרוזת,
החליף אותה בלי מהומה,
הוסיף שורה בקצה הקובץ,
שמר תגיות ומטא-דאטה,
והרשאת write שמרה על השער.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed הכותרת ברורה, קצרה, ומתארת במדויק את הוספת edit_file/append_file לעריכות חלקיות.
Description check ✅ Passed ה־PR כולל תיאור ברור של השינוי, המניע, הבדיקות והתועלת; רק חלקים פורמליים מהתבנית לא מולאו במלואם.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/mcp-codekeeper-webapp-ldnzsg

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown

⏱️ Performance report

(No performance test durations collected. Mark tests with @pytest.mark.performance.)

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown

📖 Documentation Preview

The documentation has been built successfully!

To view locally:

  1. Download the artifacts
  2. Extract the zip file
  3. Open index.html in your browser

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@FEATURE_SUGGESTIONS/FEATURE_MCP_CLAUDE_INTEGRATION.md`:
- Line 215: יישר את טבלאות מפת הדרכים וכלי MCP עם הסטטוס הקנוני בשורה זו: בפאזה
3 הצג רק save ו־edit/append, והסר או סמן כטרם מומש את delete_file בכל המקומות
הרלוונטיים, כולל טבלת מפת הדרכים וטבלת הכלים.
- Around line 13-15: עדכנו את ניסוח אכיפת הרשאת ה־write בתיאור, והחליפו את
הביטוי „אכיפה ידנית” בתיאור מפורש שהשרת mcp_server/server.py מפעיל
require_write(ctx) לפני העברת הבקשה ל-handler.

In `@mcp_server/handlers.py`:
- Around line 186-205: The edit-save flow lacks optimistic concurrency
validation, allowing parallel edits from the same base version to overwrite one
another. Thread the expected base version through edit_file, append_file, and
_resave_edited into Repository.save_code_snippet, then reject or retry when the
current latest version no longer matches; preserve the existing behavior for
successful saves and return an explicit conflict result for stale edits.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f7de7005-37d4-42f0-9a88-00bbe36191c4

📥 Commits

Reviewing files that changed from the base of the PR and between 26b9fe2 and 6069a81.

📒 Files selected for processing (7)
  • FEATURE_SUGGESTIONS/FEATURE_MCP_CLAUDE_INTEGRATION.md
  • docs/mcp-server.rst
  • mcp_server/README.md
  • mcp_server/handlers.py
  • mcp_server/server.py
  • tests/test_mcp_edit_append.py
  • tests/test_mcp_server_build.py

Comment thread FEATURE_SUGGESTIONS/FEATURE_MCP_CLAUDE_INTEGRATION.md Outdated
Comment thread FEATURE_SUGGESTIONS/FEATURE_MCP_CLAUDE_INTEGRATION.md
Comment thread mcp_server/handlers.py
MAX_CODE_SIZE is a configurable field (default 100K chars, raisable via
env), so a fixed "100KB" in the tool docs is stale for any deployment
that raised it. Reference the config knob and its default instead, and
state the unit as characters (matching the actual len(code) gate).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNFuSyshwpRcxozVZEui5K
@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 82.19178% with 13 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
mcp_server/handlers.py 86.15% 4 Missing and 5 partials ⚠️
mcp_server/server.py 50.00% 4 Missing ⚠️

📢 Thoughts on this report? Let us know!

claude added 2 commits July 20, 2026 07:06
הוספת שלושה סעיפים למדיניות הצוות:
- "תהליך עבודה" — קודם מציגים תוכנית ומחכים לאישור, אחר כך מממשים את
  הכל בלי לדלג על חלקים.
- "כלל חשוב" — תמיד מחפשים פתרון שורשי לבאג, לא טלאי.
- "שפה" — צ'אט, מחשבות, תיאורי commit/PR והערות קוד בעברית; שמות
  משתנים/פונקציות/טבלאות באנגלית כמקובל.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNFuSyshwpRcxozVZEui5K
בעקבות סבב ביקורת:
- יישור טבלת הכלים ומפת הדרכים עם הסטטוס הקנוני: פאזה 3 מציגה כעת
  save + edit/append כמומשים, ו-delete_file מסומן "טרם מומש".
- דיוק ניסוח אכיפת ה-write: השרת (server.py) קורא require_write(ctx)
  לפני מסירת הבקשה ל-handler (במקום "אכיפה ידנית ב-handler").
- הוספת non-goal מפורש: דפדפן הריפו הוא קריאה בלבד לצמיתות — אין ולא
  תתווסף כתיבה/commit/push ל-GitHub (גם ב-FEATURE וגם ב-mcp-server.rst).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WNFuSyshwpRcxozVZEui5K
@amirbiron
amirbiron merged commit c44cb59 into main Jul 20, 2026
25 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.

2 participants