Skip to main content
Glama

write_fix

Destructive

Applies a single-file unified diff, optionally runs an allowlisted test command, and rolls the file back if tests fail. Returns test output, error and git state; no commit is created.

Instructions

Apply a unified diff to one file, optionally run tests, and attempt rollback on failure. Use when: you have reviewed the source and prepared a specific patch. Don't use when: you only need to record existing edits in Git (use git_commit instead).

Returns {success, test_output, error, rolled_back}. Successful patches also return git_state (clean, modified, untracked or no_repo) and backup (null when Git holds the original, otherwise a retained .reforge-bak path). Tests are optional; success without test_command does not mean tests ran. No commit is created. Reapplying the same diff is not idempotent.

Input Schema

NameRequiredDescriptionDefault
diff_strYesSingle-file unified diff with @@ -old_start,old_count +new_start,new_count @@ hunks (1-indexed lines). Context and removed lines must match the file at the stated positions; a mismatched patch is rejected.
file_pathYesExisting file to patch, e.g. /work/app/src/main.py; must remain within repo_root. Relative paths resolve from the server working directory.
repo_rootNoRepository boundary and test-command working directory; default null uses the server working directory. Prefer an absolute path.
test_commandNoOptional allowlisted test command, e.g. pytest or npm test. Default null skips tests. Runs without a shell from repo_root, with closed stdin and a 120-second timeout; test failure triggers file rollback.
allowed_test_commandsNoCommand-prefix allowlist; a nonempty list replaces the built-in list. Default null (or []) uses built-ins such as pytest, python -m pytest, npm test and go test. Prefixes match complete shell-split tokens; command chaining remains rejected.

Output Schema

NameRequiredDescriptionDefault
errorYes
backupNo
successYes
git_stateNo
rolled_backYes
test_outputYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed8 schema fields changedv0.4.5
    • addedInput schema / properties / allowed_test_commands / description
      Added value: +"Command-prefix allowlist; a nonempty list replaces the built-in list. Default null (or []) uses built-ins such as pytest, python -m pytest, npm test and go test. Prefixes match complete shell-split tokens; command chaining remains rejected."
    • addedInput schema / properties / diff_str / description
      Added value: +"Single-file unified diff with @@ -old_start,old_count +new_start,new_count @@ hunks (1-indexed lines). Context and removed lines must match the file at the stated positions; a mismatched patch is rejected."
    • addedInput schema / properties / file_path / description
      Added value: +"Existing file to patch, e.g. /work/app/src/main.py; must remain within repo_root. Relative paths resolve from the server working directory."
    • addedInput schema / properties / repo_root / description
      Added value: +"Repository boundary and test-command working directory; default null uses the server working directory. Prefer an absolute path."
    • addedInput schema / properties / test_command / description
      Added value: +"Optional allowlisted test command, e.g. pytest or npm test. Default null skips tests. Runs without a shell from repo_root, with closed stdin and a 120-second timeout; test failure triggers file rollback."
    • removedOutput schema / additionalProperties
      Removed value: -true
    • addedOutput schema / properties
      Added value: +{
      +  "backup": {
      +    "anyOf": [
      +      {
      +        "type": "string"
      +      },
      +      {
      +        "type": "null"
      +      }
      +    ]
      +  },
      +  "error": {
      +    "anyOf": [
      +      {
      +        "type": "string"
      +      },
      +      {
      +        "type": "null"
      +      }
      +    ]
      +  },
      +  "git_state": {
      +    "type": "string"
      +  },
      +  "rolled_back": {
      +    "type": "boolean"
      +  },
      +  "success": {
      +    "type": "boolean"
      +  },
      +  "test_output": {
      +    "anyOf": [
      +      {
      +        "type": "string"
      +      },
      +      {
      +        "type": "null"
      +      }
      +    ]
      +  }
      +}
    • addedOutput schema / required
      Added value: +[
      +  "success",
      +  "test_output",
      +  "error",
      +  "rolled_back"
      +]
  2. Addedv0.2.9

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond annotations (destructive, non-idempotent, open-world), the description discloses that no commit is created, that rollback is attempted on failure, that a .reforge-bak file may be retained, and that a diff is not safe to reapply. The caveat 'success without test_command does not mean tests ran' is a non-obvious behavioral trap that annotations cannot express.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is front-loaded (purpose, then when/when-not, then returns) and every sentence carries signal. The enumerated return-value list partially duplicates the output schema, which is the only slack in an otherwise tight definition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a five-parameter destructive patch tool with an output schema, the description covers purpose, gating conditions, rollback behavior, backup artifacts, and result interpretation. Nothing an agent needs in order to invoke it safely is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description adds meaning on top by clarifying that test_command is optional and that omitting it yields success without test execution, which changes how an agent should interpret results. It does not add nuance about allowed_test_commands beyond the schema, keeping it below 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence names a specific verb and resource ('Apply a unified diff to one file') and immediately adds the two bundled behaviors (optional test run, rollback on failure). It also explicitly distinguishes itself from the closest sibling, git_commit, so an agent can route without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides an explicit 'Use when' condition (you have reviewed the source and prepared a specific patch) and an explicit 'Don't use when' with the named alternative (git_commit for recording existing edits). This is the full when/when-not/alternative triad.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.