Skip to content

feat: add file mode (executable bit) support to push_files#2579

Open
why-pengo wants to merge 1 commit into
github:mainfrom
why-pengo:feature/push-files-mode
Open

feat: add file mode (executable bit) support to push_files#2579
why-pengo wants to merge 1 commit into
github:mainfrom
why-pengo:feature/push-files-mode

Conversation

@why-pengo
Copy link
Copy Markdown

@why-pengo why-pengo commented May 30, 2026

This is my first contribution to this repo. I used Claude Code with Opus 4.7. I reviewed the code and tried to make sure I followed contributing.md.

Summary

  • Adds an optional mode field to each entry in push_files, threaded into the Git Data API CreateTree call. Accepted values are the ones the API itself accepts: 100644 (regular file, the default when omitted), 100755 (executable), 120000 (symlink), 040000 (subtree), 160000 (submodule). Unknown values are rejected with a clear error.
  • Updates create_or_update_file's description to point callers at push_files (with a single-entry files array) when they need to land an executable file, since the Contents API can't set the mode.
  • Backwards compatible: existing callers that omit mode continue to write 100644.

Motivation

Agentic harnesses use this server to publish files into a repo on behalf of an LLM. When the produced artifact is a shell script, build helper, or other executable, the file needs the executable bit set — otherwise reviewers either have to chmod +x after merge or land a broken artifact. Today there is no in-band way to do this through the server.

In practice we observed two failure modes:

  1. Agents reporting in PR bodies that they pushed with mode 100755 when the blob in fact landed as 100644.
  2. Agents inventing a second "fix permissions" file outside the requested scope (e.g. a scripts/permissions.sh that runs chmod +x later).

Exposing mode as a first-class field closes both.

create_or_update_file is not changed in this PR because the Contents API has no mode parameter — that's a GitHub API constraint, not a server one. The description now points to push_files for that case.

Test plan

  • UPDATE_TOOLSNAPS=true go test ./... — all packages green; toolsnaps for push_files and create_or_update_file regenerated.
  • script/lint (golangci-lint v2) — 0 issues.
  • script/generate-docsREADME.md regenerated to reflect the new files[].mode field description.
  • New test cases in Test_PushFiles:
    • successful multi-file push where one entry is 100755 and another defaults to 100644 (asserts the request body sent to the Git Data API contains the correct per-entry mode);
    • rejects an unknown mode string (e.g. 0755) with a clear error;
    • rejects a non-string mode value.

Closes #2578

Adds an optional `mode` field to each entry of the push_files tool,
threaded into the Git Data API CreateTree call. Allowed values are
the modes the API itself accepts: 100644 (regular file, the default
when omitted), 100755 (executable), 120000 (symlink), 040000
(subtree), and 160000 (submodule). Unknown values are rejected with
a clear error so agentic callers can correct themselves instead of
silently writing the wrong mode.

Before this change there was no in-band way for an MCP client to
publish an executable file. Two failure modes were observed in
practice: agents hallucinating in PR bodies that they had pushed
mode 100755 when the blob actually landed as 100644, and agents
inventing a second "fix permissions" file outside the requested
scope. Exposing mode closes both gaps without breaking existing
callers, which continue to get 100644 when the field is omitted.

create_or_update_file still cannot set the executable bit because
the Contents API surfaces a fixed mode; its description now points
callers at push_files with a single-entry files array for that
case.

Closes github#2578

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@why-pengo why-pengo requested a review from a team as a code owner May 30, 2026 15:52
Copilot AI review requested due to automatic review settings May 30, 2026 15:52
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.

Add file mode (executable bit) support to push_files

1 participant