Hier sind 7 Versionen von Patchloom aufgeführt, von 13. Juli 2026 bis zur aktuellen 0.37.3. Jede verweist auf die Installationsdateien des Herstellers.
| Version | Datum | Größe | Dateien |
|---|---|---|---|
| 0.37.3Aktuell | 16. Oktober 2026 | — | 64-Bit ZIPARM64 ZIP VersionshinweisePatchloom 0.37.3
YAML is parsed without the archived unsafe-libyaml crate. Edits to ini
files, markdown lists, and document moves keep the surrounding text
instead of rewriting or deleting it.
Highlights
Unquoted yes, no, on, and off in YAML stay strings. doc set
on an ini line keeps the spaces around = and a spaced ; or #
note. md upsert-bullet puts the new item in that heading's list,
before a nested heading. doc move refuses to replace a key that
already has a value, and [0], 0, and 00 name the same array slot.
Bug fixes
- YAML was parsed with the archived unsafe-libyaml crate.
Parsing now uses noyalib. Unquoted yes, no, on, and off
stay strings. A document doc set still appends a trailing newline
when the serializer omits one (#2668).
- doc set on port = 8080 ; primary rewrote the line as port=9090.
The spaces around = disappeared and the note was deleted. The
edited line now keeps that spacing and the note. A new value that
would be read back shorter, because a space before ; or #
starts a comment, is invalid_input and the file stays unchanged.
8080;primary and foo#bar stay part of the value (#2673).
- replace told every refused file to pass --allow-absent-old.
A file that simply did not contain the pattern printed that hint.
The hint is now only for exact_old_absent, when a fuzzy candidate
was found and not written. A plain miss prints refused PATH: no_matches (#2674).
- md upsert-bullet placed the new item after a nested section.
Adding - beta under # List wrote it after the body of ## Other,
so it read as part of that section. The new item stays with the
heading's own list, before the first child heading. A bullet that
exists only under the child is not treated as already present.
A second upsert of the same item does not add it again (#2675).
- doc move onto a key that already had a value replaced that value.
Moving server.http onto server.host exited 0 and replaced
localhost with 8080. The command now returns already_exists
and leaves the file unchanged. Moving a field into an earlier array
slot no longer clears the sibling that slid into the old index (#2676).
- doc move treated [0], 0, and 00 as different array slots.
Moving items[0].child to items.0.child.nested deleted the value
and exited 0. The same destination written as items[0].child.nested
was already refused. rows[0][0] to rows.0[2] wrote the values in
the wrong order, and rows[0][0] to rows.0[1] left the array
unchanged. Those spellings are now one slot. A move into a
descendant is refused and the file stays unchanged. An object key
such as 01 is not bracket index 1 (#2677).
Numbers
───────┬─────────────────────────────────────────────────────
Metric │Notes
───────┼─────────────────────────────────────────────────────
Version│0.37.2 -> 0.37.3
───────┼─────────────────────────────────────────────────────
Focus │YAML parsing, ini lines, list bullets, document moves
───────┴─────────────────────────────────────────────────────
Upgrading
- If a YAML file relied on unquoted yes, no, on, or off as
booleans, those values are strings now. Quote them only when you
want a string that would otherwise be a number or a boolean (true,
false, null).
- doc move onto an existing key returns already_exists and does
not write. Move to a free key, or delete the destination first.
- replace no longer suggests --allow-absent-old for a file that
has no match. Pass that flag only when you mean to accept a fuzzy
candidate.
- Install from crates.io, npm, Homebrew, or Scoop after the tag
ships. On Windows, Scoop is recommended. winget may need
winget source update after Microsoft publishes. Chocolatey can
lag while moderation runs.
Full changelog
patchloom-v0.37.2...patchloom-v0.37.3 |
| 0.37.2 | 11. Oktober 2026 | — | 64-Bit ZIPARM64 ZIP VersionshinweisePatchloom 0.37.2
TOML integers that do not fit in a signed 64-bit value stay exact.
A plan key that does not belong on an edit is reported instead of
changing the edit. A preview of renaming a binary file or a directory
names the move.
Highlights
doc set writes a TOML integer above 9223372036854775807 as bare
digits, and doc get reads that same integer back. A plan or MCP
call that puts a key on the wrong object now warns, or refuses the
edit, instead of applying a different change. rename of a binary
file or a directory prints would rename in the default preview.
Bug fixes
- A TOML integer above i64::MAX became a rounded float.
9223372036854775808 was written as 9223372036854776000.0, and
doc get then rejected the exact digits as integer number overflowed.
Values that fit in u64 but not i64 round-trip as bare digits. A
same-line comment survives a sibling edit. A digit token above
u64::MAX stays that exact decimal text, written as a quoted string
on a new key, instead of a rounded float (#2655).
- An ini header that never closed kept later keys in the previous section.
[broken is a parse error. A ] inside an inline ; or # comment
stays part of that comment. Junk after the header is still a parse
error. batch points notebook.edit at a tx plan or the MCP
notebook_edit tool (#2657).
- An inline MCP plan ignored expected_sha256 on the operation.
The file was written and the tool result had no warnings entry.
That key on the operation now returns warnings naming
expected_sha256, and the write still happens. The pin that stops
a stale write is still the plan map expected_sha256: a wrong hash
there returns error_kind: stale and leaves the file unchanged (#2659).
- A reused MCP worker copied the previous plan warning into the next tool.
A later doc_set could include the last execute_plan unknown-key
warning. Each tool call now clears that leftover. The plan that had
the bad key still warns, and it still applies (#2660).
- notebook.edit warned that id was unknown while still using it.
The cell source changed and the result also warned. id is accepted.
A real unknown key on that operation still warns (#2660).
- verify treated attribute as absent and counted every function.
Removing a non-test function then failed verification and wrote
nothing, while the same plan with attr applied. attribute is now
invalid_input and the file stays unchanged. attr still applies.
Other unknown operation keys and top-level keys still warn only (#2660).
- Preview of rename on a binary file or a directory printed nothing.
The command exited 2 and left both paths in place. rename --check
already printed would rename FROM -> TO (binary) or (directory).
Default preview now prints that line and still does not write. Text
files still show the usual diff. JSON still has from, to, and
applied: false (#2666).
- An env or ini write that would split the file, or read back as another key, is refused.
doc set returns invalid_input and leaves the file unchanged. A #
comment after a space, or after a closing quote, is not part of the
value. A # glued to the value stays in the value. A new properties
key escapes backslashes, separators, newlines, and a leading # or
! so the line stays one assignment (#2657).
Numbers
───────┬─────────────────────────────────────────────────────────────────
Metric │Notes
───────┼─────────────────────────────────────────────────────────────────
Version│0.37.1 -> 0.37.2
───────┼─────────────────────────────────────────────────────────────────
Focus │Exact TOML integers, ini and env lines, plan keys, rename preview
───────┼─────────────────────────────────────────────────────────────────
Tests │5800+ (README badge on main)
───────┴─────────────────────────────────────────────────────────────────
Upgrading
- An ini file whose section header never closes now fails to parse.
Close the header, or move those keys into a closed section.
- A plan verify step that says attribute instead of attr is
invalid_input and does not write. Use attr.
- An oper |
| 0.37.1 | 8. Oktober 2026 | — | 64-Bit ZIPARM64 ZIP VersionshinweisePatchloom 0.37.1
Format commands stop when the timeout is reached, even if a child
process still holds stderr. A parent config outside a git repository
no longer supplies those commands.
Highlights
A formatter that closes stderr and keeps running, or a shell that exits
while a background process holds stderr, is killed at
--format-timeout (30 seconds unless you set another value). The
result is error_kind: format_failed. Outside git, write policy from a
parent .patchloom.toml still applies, and format commands from that
parent are dropped.
Bug fixes
- A format command could run past its timeout. Closing stderr, or
leaving a background process holding stderr, no longer drops the
deadline. Patchloom kills that process tree and returns
format_failed. The same timeout applies to --format,
[defaults] format, [format] command, and [format.by_extension].
A per-extension formatter that exits non-zero still warns, and the
write stays (#2643, #2648, #2650).
- A failed hardlink rewrite could leave the shared file damaged.
Patchloom writes the staged bytes back onto the original inode. If
that restore also fails, the error names the staged file only when
the file was kept (#2643).
- A parent config outside git could run a shell. Walk-up still
loads write policy. [defaults] format, [format] command, auto,
and by_extension from an ancestor are dropped when there is no
.git directory above the start path. A symlink
.patchloom.toml is refused and its target is not read. A parse
error names the config path and the first error line (#2643).
- --contain read a path before rejecting it. Git copy from,
Begin Patch check, patch merge check, markdown lint, markdown
dedupe, and a batch @path payload are checked before the file is
read. A path outside the workspace is guard_rejected (#2643, #2645).
- A short hunk was applied as a complete edit. A hunk that ends
before its line counts are satisfied is a parse error. A git copy
that also has hunks keeps the source file and applies the hunks to
the copy (#2643).
- Replace context skipped regex and whole-line matches. Those
matches now honor before_context and after_context. A literal
replacement keeps $ as text. In regex mode, $1 is still a
capture (#2643).
- --files-without-match --assert-count counted every file as
zero. The count is the number of files listed (#2643).
- An exclude pattern such as _* skipped every directory.
Directories that still contain files you asked to edit are walked (#2643).
- JSON, TOML, YAML, and markdown edits dropped nearby text. A
JSONC block comment between numbers no longer glues them into one
number. A TOML integer above 9223372036854775807 stays a decimal
integer. A YAML comment after the last list entry stays after the
list. Markdown section edits recognize setext headings, a leading
BOM, closing hashes, and a blank line between sections.
md dedupe-headings says would remove in the dry-run text (#2643).
- Signature edits dropped nearby tokens. A Java visibility change
leaves static and annotations in place. A C or C++ return-type
edit keeps const and volatile on that type. Moving a Rust symbol
to the start of a file no longer treats #![ as a shebang. A short
fuzzy string is not applied to a much longer name. A plan format
step still runs when the replace did not change the file. A plan key
named command is reported as unknown instead of ignored (#2643).
- PHP parsing uses tree-sitter-php 0.25 (#2649).
Numbers
───────┬──────────────────────────────────────────────────────────
Metric │Notes
───────┼──────────────────────────────────────────────────────────
Version│0.37.0 -> 0.37.1
───────┼──────────────────────────────────────────────────────────
Focus │Format timeouts, containment before reads, edit edge cases
───────┼──────────────────────────────────────────────────────────
Tests │5700+ (README badge, unchanged this release)
───────┴──────────────────────────────────────────────────────────
Upgrading
- A config or per-extension formatter that hits the timeout now exit |
| 0.33.0 | 8. September 2026 | — | 64-Bit ZIPARM64 ZIP VersionshinweisePatchloom 0.33.0
Windows dests, globs, and line endings now follow the same rules as
Linux. Library hosts can set charset on writes.
Highlights
A dest like *.txt matches files in the current directory only.
sub/*.txt stays in that directory. Use **/*.txt or --glob '*.txt'
when you want nested files. On Windows the CLI expands those dest
patterns itself (cmd.exe does not).
WritePolicyOptions.charset and EditorConfig charset = utf-8-bom
write a leading U+FEFF. charset = utf-8 does not insert one.
utf-16le is invalid_input. api::tidy applies the same charset
when it is not Keep.
A leading UTF-8 BOM is outside regex ^. A lone CR is a line end
for search, replace $, markdown headings, AST lines, and
read --lines.
Breaking changes
WritePolicy and WritePolicyOptions are #[non_exhaustive] and
have a new charset field (CharsetMode, default Keep). Construct
with Default and ..:
let opts = WritePolicyOptions {
charset: CharsetMode::Utf8Bom,
..WritePolicyOptions::default()
};
CharsetMode is re-exported from patchloom::api and the crate
root (#2372).
New features
- Dest globs on search, replace, and tidy. *.txt is the current
directory only. sub/*.txt is that directory only (not cwd, not
nested). **/*.txt is recursive. --glob '*.txt' still walks
nested files. A miss names dest vs --glob and skips the -i tip
when the dest glob was empty or cwd-only. Plan, tx, and MCP path
is one file or directory: do not put *.txt there. Use replace
"glob" or plan-level for_each.glob (#2368, #2370, #2371).
- Charset on library writes. Set WritePolicyOptions.charset to
Utf8Bom or Utf8. api::tidy honors a non-Keep charset locally
(plan TidyFix has no charset field). Indent then charset, so a
BOM stays on the first byte. Setting both dedent and indent is
invalid_input (#2372, #2373).
- EditorConfig charset. With --respect-editorconfig,
charset = utf-8-bom writes U+FEFF and charset = utf-8 does not
insert one. utf-16le / utf-16be are invalid_input (#2358).
- Protobuf AST 0.6. ast list / ast rename on .proto files
use tree-sitter-proto 0.6 (#2374).
Bug fixes
- Windows dests ignored --cwd or deleted the file. C:foo and
\foo dests are invalid_input (they ignore --cwd). A trailing
slash on a dest no longer treats the file as missing or rolls back
a create. Drive-relative --files-from lines peel the same way.
Bare NUL is invalid_input. Illegal dests (<>"|?*, \\.,
trailing space or dot) peel before open (#2360, #2362, #2364, #2366, #2354, #2307).
- --glob *.txt missed Hit.TXT on Windows. User globs and
.gitignore match case-insensitively on Windows (#2309, #2310).
- Writes dropped hardlinks, MOTW, and named streams. A Windows
hardlink pair stays linked after Apply. Zone.Identifier and
custom NTFS streams persist through atomic rename. Destinations
past MAX_PATH persist. An 8.3 dest keeps the long name (#2303, #2312, #2356, #2313, #2306).
- --contain rejected local UNC and //?/ dests. Local
admin-share UNC (\\localhost\C$\...) maps into the workspace.
IPv6 loopback UNC is local, not an ADS path. //?/C:/ dests
inside the workspace apply, and backup opens them with a
drive-letter path. \\.\C:\ dests that name a real file apply (#2314, #2315, #2321, #2319, #2323).
- Notepad UTF-8 BOM and CR-only files missed matches. JSON,
markdown, prepend, and tx plans accept a leading BOM. Multi-doc
YAML strips the BOM before parse. Regex ^ skips a leading BOM.
A lone CR is a line end for search, markdown, TOML, AST lines,
read --lines, and replace $ (including mid-file CR). Indent
and dedent peel a leading BOM so the first line is not treated
as indented text (#2311, #2316, #2317, #2330, #2331, #2335, #2336, #2337, #2343, #2347, #2326, #2348, #2374).
- Patch dests with a\ stayed not_found. Git headers
a\file and b\file strip like a/ / b/. Mixed grammar
(unified headers plus SEARCH/REPLACE) is invalid_input (#2349, #2351).
- Quoted YAML C:\Users was a unicode escape. A drive-letter
:\\ path in a quoted YAML plan is invalid_input and names
/ or \\\\ as the fix (#2357).
- UTF-16 --files |
| 0.32.0 | 2. September 2026 | — | 64-Bit ZIPARM64 ZIP VersionshinweisePatchloom 0.32.0
YAML merge-key edits keep shared mappings, sibling anchors, and
comments instead of rewriting the whole file. Patch deletes report
a change and apply hunks before unlink, so leftover lines stay on
disk.
Highlights
doc set on a YAML merge (<<: *shared) now keeps the merge key
when you grow an inherited array, delete an inherited field, or
write an empty object. Sibling &anchor lines stay. Empty {}
and [] keep comments and spacing instead of rewriting the
whole file.
apply_patch on a git delete reports changed: true and empty
new_content. A hunked +++ /dev/null applies the minus lines
first. Leftover text is written back. A stale minus is
error_kind: ambiguous (exit 5) and the file is left unchanged.
New features
- Library doc_keys and doc_len. Hosts can list object keys
and count array or object length without going through CLI or
MCP. Empty / "." is the document root. An array on doc_keys
is type_error. A wildcard or predicate (items[*]) is
ambiguous and names items[0] / items[1]. A missing file
is not_found.
let keys = patchloom::api::doc_keys(path, "database")?;
let n = patchloom::api::doc_len(path, "items")?;
CLI doc keys / doc len and MCP doc_query use the same
rules (#2282, #2284).
- Blank YAML is an empty object on read. doc keys, doc len, and doc get . treat an empty, whitespace-only, or
BOM/ZWSP-only YAML file as {}. Comment-only YAML, null,
and a bare --- still return type_error on keys and len (#2285, #2286).
- Protobuf AST kinds. ast list and ast rename on .proto
files include Status and enum symbols. Kind filters accept
message, service, and rpc as well as the tree-sitter
names (#2264, #2265).
Bug fixes
- YAML merge edits dumped the file or dropped <<:. Growing
an inherited array, deleting an inherited key, or expanding a
merge-only site now keeps the merge key, sibling anchors, and
comments. A merge-only site that becomes empty writes {} (#2270, #2271, #2272, #2273).
- Emptying a YAML sequence item glued the next line. Setting
a non-last item to {} or [] used to drop the item newline
(- {} - name: B) and dump the file. The item stays on its
own line and comments remain (#2277, #2281).
- Mixed flow and block aliases dumped the file. A flow
[*shared] next to a later - *shared no longer rewrites the
whole document. Merge-key walks stop at depth 128 (#2267, #2265).
- apply_patch delete looked unchanged. An empty-hunk git
delete (deleted file mode, no hunks) now reports
changed: true and empty new_content. Regular files are
snapshotted for undo. Symlink, FIFO, and socket snapshots stay
empty so target bytes are not copied into the result (#2287, #2289).
- Hunked delete unlinked first and dropped leftover lines. A
+++ /dev/null patch with minus hunks now applies those hunks
before unlink. Leftover text is written back. A stale minus is
ambiguous (exit 5) and the file stays (#2294).
- Add-only hunks wiped a symlink target. Content patches load
the symlink target instead of treating every special path as
empty. Empty-hunk delete snapshots stay empty (#2293).
Numbers
───────┬──────────────────────────────────────────────────────
Metric │Notes
───────┼──────────────────────────────────────────────────────
Version│0.31.0 -> 0.32.0
───────┼──────────────────────────────────────────────────────
Focus │YAML merge edits, apply_patch delete, doc_keys /
│doc_len
───────┼──────────────────────────────────────────────────────
Tests │4800+ (3268 unit + 1553 integration + 10 PTY)
───────┴──────────────────────────────────────────────────────
Upgrading
- Agents: doc keys / doc len on a wildcard or predicate
(items[*]) is ambiguous, even when there is one match. A
missing file is not_found. Blank YAML keys/len/get treat the
document as {}.
- Library hosts: api::doc_keys and api::doc_len are new.
apply_patch empty-hunk delete now sets changed: true and
empty new_content. Hunked +++ /dev/null applies minus lines
first; leftover text is a write, not an unlink. Content patches
follow symlink targets. Empty-hunk delete snaps |
| 0.27.0 | 4. August 2026 | — | 64-Bit ZIPARM64 ZIP VersionshinweisePatchloom 0.27.0
Clearer agent recovery after failed writes, and machine-stable hints when a
doc write selector uses a predicate or wildcard.
Highlights
Library hosts can read a backup session id from a failed apply path so
fail-restore and undo do not scrape English error text. When doc set,
doc ensure, or doc delete is called with a predicate or wildcard
selector, JSON output can include suggested_op (doc.update or
doc.delete_where) so harnesses can retry the right multi-match op without
parsing messages. That mapping also holds when the predicate is an intermediate
parent path, not only a leaf segment.
New features
- api::backup_session_from_error. On a failed write after a backup was
created (for example a post-write --format failure), hosts can peel the
session id from the error for fail-restore. Success paths already expose
EditResult.backup_session; the Err path is now first-class.
(#2129, #2131)
- suggested_op on fail-closed write navigation. Predicate or wildcard
selectors on single-path doc writes stay error_kind: invalid_input and
may set suggested_op to doc.update (set/ensure) or doc.delete_where
(delete). Plan/tx and MCP JSON preserve the field. Move has no multi-match
sibling and omits the field. Intermediate parents use the same mapping as
leaves.
(#2136, #2137, #2140)
Bug fixes
- Tx JSON could drop suggested_op after re-wrap. Fail-closed predicate
navigation still surfaces the hint on CLI and library peels after plan
error packaging. (#2137)
- Intermediate predicate always suggested doc.update. A delete (or
move) path such as items[id=a].val no longer invents an update retry;
delete suggests doc.delete_where, and move omits suggested_op.
(#2140)
Docs
- Agent and reference guidance for doc set vs doc update, and when to
branch on suggested_op. Intermediate mapping documented on set/delete.
(#2135, #2143)
Numbers
───────┬──────────────────────────────────────────────────────
Metric │Notes
───────┼──────────────────────────────────────────────────────
Version│0.26.0 → 0.27.0
───────┼──────────────────────────────────────────────────────
Focus │Fail-restore session peel, write-nav suggested_op,
│docs
───────┼──────────────────────────────────────────────────────
Tests │4100+ (rounded badge)
───────┴──────────────────────────────────────────────────────
Upgrading
- Library hosts: on apply Err after a backup, use
api::backup_session_from_error(&err) (or the crate re-export) instead of
parsing Display for a session id.
- Agents / harnesses: on invalid_input from doc write navigation,
read suggested_op when present. Do not assume every intermediate
failure means doc.update.
- Install from crates.io, npm, Homebrew, or Scoop after the tag ships.
Winget and Chocolatey may lag. Fresh Homebrew installs are checked in
release CI; local cellars still need brew upgrade when an older
formula is already installed.
Full changelog
patchloom-v0.26.0...patchloom-v0.27.0 |
| 0.13.0 | 13. Juli 2026 | — | 64-Bit ZIPARM64 ZIP |