Repository navigation
v0.7.0
Everything here came out of measuring what an agent actually does with the tool, rather than what it could do. Twelve controlled runs — separate claude -p processes, byte-identical worktrees, tool calls and cost read from each run's own JSON — and then reading the transcripts to find out where the calls went.
The catalogue says what each operation takes
contexts listed operation names and nothing else, so a caller had to guess the argument names, and guessed by analogy with whatever it had seen last. Asked to rename a variable, a model sent expect and value — set_name's shape — three times over, met Expected node name $nonce, got createChallengeToken each time, and then abandoned selectors for hand-guessed refs and renamed one scope at a time, leaving two of eleven occurrences behind. A confusing message did not only cost turns; it cost the result.
operationArguments is published, the check runs before the target's own expect so the message is about the edit, and the message shows the shape rather than listing field names — naming them was not enough, the same model then put from and to inside value. Same task, same model, against this build: 15 turns and a wrong result became 6 turns with no failed apply at all.
Two operations that were missing
rename_method moves a declaration and the calls to it in one edit. What counts as a call to this method is decided structurally — $this->, self::, static::, parent:: inside the declaring class, and not inside a nested anonymous class — with names compared the way PHP resolves them, without regard to ASCII case. A call on any other receiver is counted, not touched. Locating call sites by hand had cost four inspect calls per rename; that task went from 13 turns to 5.
property: now finds promoted constructor properties. On the extension this was measured against, 58 of 65 properties are promoted and 7 are declared in the class body, so the selector had been finding the exception and missing the rule.
The write answers for itself
verify lets a repository declare the checks it wants run — PHPStan, the coding-standards check — executed after the formatter on what will be committed, reported as ok with the output of anything that failed. A failing check does not roll the write back: the code is written and it parses, and what failed is an opinion about it.
The report also carries valid, effects — what each edit did, and for a rename how much of the old name the file still holds — and diff. INCOMPLETE_RENAME appears beside the result rather than only in the count, because a model read remainingInFile: 2 and stopped anyway.
Thanks to @CybotTM for the reviews across this series, which caught a hand-written argument table that was wrong where it mattered, verifyResults leaking between calls, and both the nested-class and the case-sensitivity holes in rename_method.
Upgrading
Nothing is removed. verify is opt-in; without it the write behaves as before. The report gains fields, so a consumer parsing it strictly should expect valid, effects, diff and verify to appear.
Full Changelog: v0.6.1...v0.7.0