Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package ast-grep for openSUSE:Factory 
checked in at 2026-10-16 20:09:53
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ast-grep (Old)
 and      /work/SRC/openSUSE:Factory/.ast-grep.new.3698736 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ast-grep"

Fri Oct 16 20:09:53 2026 rev:80 rq:1385156 version:0.51.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/ast-grep/ast-grep.changes        2026-10-12 
22:07:59.605238297 +0200
+++ /work/SRC/openSUSE:Factory/.ast-grep.new.3698736/ast-grep.changes   
2026-10-16 20:13:47.946532396 +0200
@@ -1,0 +2,15 @@
+Fri Oct 16 08:50:05 UTC 2026 - Michael Vetter <[email protected]>
+
+- Update to version 0.51.0:
+  * 0.51.0 bump version
+  * fix(cli): use `ast-grep` name in project setup hint (#3001)
+  * Revise security policy for clarity and updates
+  * fix: replace deprecated serde_yaml with serde-saphyr (#2999)
+  * fix(deps): update rust crate tree-sitter-haskell to 0.24.0 (#2988)
+  * fix(cli): preserve files when update-all writes fail (#2995)
+  * fix: update wasm linting
+- Drop because tree-sitter-haskell got updated to 0.24.0:
+  * tree-sitter-haskell-fix-heap-corruption-checksum.patch
+  * tree-sitter-haskell-fix-heap-corruption.patch
+
+-------------------------------------------------------------------
@@ -42,0 +58,9 @@
+
+-------------------------------------------------------------------
+Fri Sep 25 07:04:20 UTC 2026 - Andrei Dziahel <[email protected]>
+
+- Fix heap corruption ("corrupted size vs. prev_size") in the vendored
+  Haskell parser caused by strict-aliasing UB in tree_sitter/array.h
+  (tree-sitter/tree-sitter-haskell#158, upstream fix from PR #157):
+  * tree-sitter-haskell-fix-heap-corruption.patch
+  * tree-sitter-haskell-fix-heap-corruption-checksum.patch

Old:
----
  ast-grep-0.50.0.tar.zst

New:
----
  ast-grep-0.51.0.tar.zst

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ast-grep.spec ++++++
--- /var/tmp/diff_new_pack.d8jJHh/_old  2026-10-16 20:13:49.304589426 +0200
+++ /var/tmp/diff_new_pack.d8jJHh/_new  2026-10-16 20:13:49.307589552 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           ast-grep
-Version:        0.50.0
+Version:        0.51.0
 Release:        0
 Summary:        A CLI tool for code structural search, lint and rewriting
 License:        MIT

++++++ _service ++++++
--- /var/tmp/diff_new_pack.d8jJHh/_old  2026-10-16 20:13:49.373592324 +0200
+++ /var/tmp/diff_new_pack.d8jJHh/_new  2026-10-16 20:13:49.377592492 +0200
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/ast-grep/ast-grep.git</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="scm">git</param>
-    <param name="revision">0.50.0</param>
+    <param name="revision">0.51.0</param>
     <param name="match-tag">*</param>
     <param name="versionrewrite-pattern">v(\d+\.\d+\.\d+)</param>
     <param name="versionrewrite-replacement">\1</param>

++++++ ast-grep-0.50.0.tar.zst -> ast-grep-0.51.0.tar.zst ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/CHANGELOG.md 
new/ast-grep-0.51.0/CHANGELOG.md
--- old/ast-grep-0.50.0/CHANGELOG.md    2026-10-07 16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/CHANGELOG.md    2026-10-15 17:05:11.000000000 +0200
@@ -4,8 +4,19 @@
 
 Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
 
+#### [0.51.0](https://github.com/ast-grep/ast-grep/compare/0.50.0...0.51.0)
+
+- fix(cli): use `ast-grep` name in project setup hint 
[`#3001`](https://github.com/ast-grep/ast-grep/pull/3001)
+- fix: replace deprecated serde_yaml with serde-saphyr 
[`#2999`](https://github.com/ast-grep/ast-grep/pull/2999)
+- fix(deps): update rust crate tree-sitter-haskell to 0.24.0 
[`#2988`](https://github.com/ast-grep/ast-grep/pull/2988)
+- fix(cli): preserve files when update-all writes fail 
[`#2995`](https://github.com/ast-grep/ast-grep/pull/2995)
+- Revise security policy for clarity and updates 
[`a7d3f69`](https://github.com/ast-grep/ast-grep/commit/a7d3f6935320f9859c3d522d133aabba21ccff4c)
+- fix: update wasm linting 
[`ea55463`](https://github.com/ast-grep/ast-grep/commit/ea5546303f4aebe86c16a3fada2dae0372bd95c4)
+
 #### [0.50.0](https://github.com/ast-grep/ast-grep/compare/0.45.3...0.50.0)
 
+> 7 October 2026
+
 - feat(outline): add Java annotation type and element rules 
[`#2955`](https://github.com/ast-grep/ast-grep/pull/2955)
 - fix(outline): report Java private/protected fields in the outline 
[`#2950`](https://github.com/ast-grep/ast-grep/pull/2950)
 - feat(outline): add Java enum member rule 
[`#2954`](https://github.com/ast-grep/ast-grep/pull/2954)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/Cargo.lock 
new/ast-grep-0.51.0/Cargo.lock
--- old/ast-grep-0.50.0/Cargo.lock      2026-10-07 16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/Cargo.lock      2026-10-15 17:05:11.000000000 +0200
@@ -22,6 +22,17 @@
 ]
 
 [[package]]
+name = "annotate-snippets"
+version = "0.12.16"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "f211a51805bc641f3ad5b7664c77d2547af685cc33b4cd8d31964027a46f13f1"
+dependencies = [
+ "anstyle",
+ "memchr",
+ "unicode-width 0.2.2",
+]
+
+[[package]]
 name = "ansi_term"
 version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -87,6 +98,12 @@
 checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
 
 [[package]]
+name = "arraydeque"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236"
+
+[[package]]
 name = "assert_cmd"
 version = "2.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -103,7 +120,7 @@
 
 [[package]]
 name = "ast-grep"
-version = "0.50.0"
+version = "0.51.0"
 dependencies = [
  "ansi_term",
  "anyhow",
@@ -126,9 +143,9 @@
  "predicates",
  "regex",
  "serde",
+ "serde-saphyr",
  "serde-sarif",
  "serde_json",
- "serde_yaml",
  "similar",
  "smallvec",
  "tempfile",
@@ -141,7 +158,7 @@
 
 [[package]]
 name = "ast-grep-config"
-version = "0.50.0"
+version = "0.51.0"
 dependencies = [
  "ast-grep-core",
  "bit-set",
@@ -149,15 +166,16 @@
  "regex",
  "schemars",
  "serde",
+ "serde-saphyr",
+ "serde-value",
  "serde_regex",
- "serde_yaml",
  "thiserror 2.0.21",
  "tree-sitter-typescript",
 ]
 
 [[package]]
 name = "ast-grep-core"
-version = "0.50.0"
+version = "0.51.0"
 dependencies = [
  "bit-set",
  "regex",
@@ -168,13 +186,13 @@
 
 [[package]]
 name = "ast-grep-dynamic"
-version = "0.50.0"
+version = "0.51.0"
 dependencies = [
  "ast-grep-core",
  "ignore",
  "libloading",
  "serde",
- "serde_yaml",
+ "serde-saphyr",
  "target-triple",
  "thiserror 2.0.21",
  "tree-sitter",
@@ -182,7 +200,7 @@
 
 [[package]]
 name = "ast-grep-language"
-version = "0.50.0"
+version = "0.51.0"
 dependencies = [
  "ast-grep-core",
  "ignore",
@@ -220,7 +238,7 @@
 
 [[package]]
 name = "ast-grep-lsp"
-version = "0.50.0"
+version = "0.51.0"
 dependencies = [
  "anyhow",
  "ast-grep-config",
@@ -238,7 +256,7 @@
 
 [[package]]
 name = "ast-grep-napi"
-version = "0.50.0"
+version = "0.51.0"
 dependencies = [
  "ast-grep-config",
  "ast-grep-core",
@@ -254,21 +272,21 @@
 
 [[package]]
 name = "ast-grep-outline"
-version = "0.50.0"
+version = "0.51.0"
 dependencies = [
  "ast-grep-config",
  "ast-grep-core",
  "ast-grep-language",
  "regex",
  "serde",
+ "serde-saphyr",
  "serde_json",
- "serde_yaml",
  "thiserror 2.0.21",
 ]
 
 [[package]]
 name = "ast-grep-py"
-version = "0.50.0"
+version = "0.51.0"
 dependencies = [
  "anyhow",
  "ast-grep-config",
@@ -298,6 +316,12 @@
 checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
 
 [[package]]
+name = "base64"
+version = "0.23.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5"
+
+[[package]]
 name = "bit-set"
 version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -497,6 +521,12 @@
 ]
 
 [[package]]
+name = "core_detect"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "7f8f80099a98041a3d1622845c271458a2d73e688351bf3cb999266764b81d48"
+
+[[package]]
 name = "crokey"
 version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -690,6 +720,29 @@
 checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
 
 [[package]]
+name = "encoding_rs"
+version = "0.8.42"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "8e985e0451871ad22fb8d2b6b076e2028a502a0d3950998c2c5c0a4f9b5d9679"
+dependencies = [
+ "cfg-if",
+ "core_detect",
+ "multiversion_no_op",
+ "rustversion",
+ "scopeguard",
+ "simdutf8",
+]
+
+[[package]]
+name = "encoding_rs_io"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "fba3fe847045ecff794b9c138293a80db914678c453ad63fbf0c6a9eb6e00b22"
+dependencies = [
+ "encoding_rs",
+]
+
+[[package]]
 name = "equivalent"
 version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -875,6 +928,16 @@
 ]
 
 [[package]]
+name = "granit-parser"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "da55feca5d1625466bae068f9fd4b87892caeae70c3fe671ddb0f50d41aebf37"
+dependencies = [
+ "arraydeque",
+ "smallvec",
+]
+
+[[package]]
 name = "hashbrown"
 version = "0.14.5"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -1108,6 +1171,12 @@
 ]
 
 [[package]]
+name = "multiversion_no_op"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "743fb55ba31b18fb1ecef6bdc9aa2743314978ac084044301a7eee33fb99a20d"
+
+[[package]]
 name = "napi"
 version = "3.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -1236,6 +1305,15 @@
 checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
 
 [[package]]
+name = "ordered-float"
+version = "2.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
 name = "parking_lot"
 version = "0.12.5"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -1520,12 +1598,6 @@
 checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
 
 [[package]]
-name = "ryu"
-version = "1.0.23"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
-
-[[package]]
 name = "same-file"
 version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -1609,6 +1681,23 @@
 ]
 
 [[package]]
+name = "serde-saphyr"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "a253edfdea34032da21af84e16fcc94f4c7a6ba237f9f3bc2dbf43cea8535c44"
+dependencies = [
+ "annotate-snippets",
+ "base64",
+ "encoding_rs_io",
+ "granit-parser",
+ "nohash-hasher",
+ "num-traits",
+ "serde_core",
+ "smallvec",
+ "zmij",
+]
+
+[[package]]
 name = "serde-sarif"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -1629,6 +1718,16 @@
 ]
 
 [[package]]
+name = "serde-value"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
+dependencies = [
+ "ordered-float",
+ "serde",
+]
+
+[[package]]
 name = "serde-wasm-bindgen"
 version = "0.6.5"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -1695,19 +1794,6 @@
 ]
 
 [[package]]
-name = "serde_yaml"
-version = "0.9.34+deprecated"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
-dependencies = [
- "indexmap",
- "itoa",
- "ryu",
- "serde",
- "unsafe-libyaml",
-]
-
-[[package]]
 name = "sharded-slab"
 version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -1754,6 +1840,12 @@
 ]
 
 [[package]]
+name = "simdutf8"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
+
+[[package]]
 name = "similar"
 version = "3.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -2252,9 +2344,9 @@
 
 [[package]]
 name = "tree-sitter-haskell"
-version = "0.23.1"
+version = "0.24.1"
 source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "977c51e504548cba13fc27cb5a2edab2124cf6716a1934915d07ab99523b05a4"
+checksum = "781de30e0d1ec8e6db4ed799d36ce1cedaf4684374dada45ebe2a8ea44c3f814"
 dependencies = [
  "cc",
  "tree-sitter-language",
@@ -2501,12 +2593,6 @@
 checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
 
 [[package]]
-name = "unsafe-libyaml"
-version = "0.2.11"
-source = "registry+https://github.com/rust-lang/crates.io-index";
-checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
-
-[[package]]
 name = "uriparse"
 version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index";
@@ -2555,7 +2641,7 @@
 
 [[package]]
 name = "wasm"
-version = "0.50.0"
+version = "0.51.0"
 dependencies = [
  "ast-grep-config",
  "ast-grep-core",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/Cargo.toml 
new/ast-grep-0.51.0/Cargo.toml
--- old/ast-grep-0.50.0/Cargo.toml      2026-10-07 16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/Cargo.toml      2026-10-15 17:05:11.000000000 +0200
@@ -10,30 +10,30 @@
 lto = true
 
 [workspace.package]
-version = "0.50.0"
+version = "0.51.0"
 authors = ["Herrington Darkholme 
<[email protected]>"]
 edition = "2024"
 license = "MIT"
 documentation = "https://ast-grep.github.io/guide/introduction.html";
 homepage = "https://ast-grep.github.io/";
 repository = "https://github.com/ast-grep/ast-grep";
-rust-version = "1.88.0"
+rust-version = "1.90.0"
 readme = "README.md"
 
 [workspace.dependencies]
-ast-grep-core = { path = "crates/core", version = "0.50.0", default-features = 
false }
-ast-grep-config = { path = "crates/config", version = "0.50.0" }
-ast-grep-dynamic = { path = "crates/dynamic", version = "0.50.0" }
-ast-grep-language = { path = "crates/language", version = "0.50.0" }
-ast-grep-lsp = { path = "crates/lsp", version = "0.50.0" }
-ast-grep-outline = { path = "crates/outline", version = "0.50.0" }
+ast-grep-core = { path = "crates/core", version = "0.51.0", default-features = 
false }
+ast-grep-config = { path = "crates/config", version = "0.51.0" }
+ast-grep-dynamic = { path = "crates/dynamic", version = "0.51.0" }
+ast-grep-language = { path = "crates/language", version = "0.51.0" }
+ast-grep-lsp = { path = "crates/lsp", version = "0.51.0" }
+ast-grep-outline = { path = "crates/outline", version = "0.51.0" }
 
 bit-set = { version = "0.11.0" }
 ignore = { version = "0.4.22" }
 regex = { version = "1.10.4" }
 serde = { version = "1.0.200", features = ["derive"] }
 serde_regex = "1.2.0"
-serde_yaml = "0.9.33"
+serde-saphyr = { version = "2.0.0", default-features = false, features = 
["serialize", "deserialize"] }
 tree-sitter = { version = "0.27.0" }
 thiserror = "2.0.0"
 schemars = "1.0.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/SECURITY.md 
new/ast-grep-0.51.0/SECURITY.md
--- old/ast-grep-0.50.0/SECURITY.md     1970-01-01 01:00:00.000000000 +0100
+++ new/ast-grep-0.51.0/SECURITY.md     2026-10-15 17:05:11.000000000 +0200
@@ -0,0 +1,30 @@
+# Security Policy
+
+## Supported Versions
+
+Security fixes are provided for the latest stable release of ast-grep. Please
+upgrade to the latest release before checking whether a suspected vulnerability
+is still present.
+
+## Reporting a Vulnerability
+
+Please report suspected security vulnerabilities in ast-grep, including its CLI
+and language bindings, through [GitHub's private vulnerability reporting 
form](https://github.com/ast-grep/ast-grep/security/advisories/new).
+
+Do not disclose vulnerability details in public issues, discussions, or pull
+requests before maintainers have had an opportunity to investigate and address
+the report.
+
+To help us assess your report, include:
+
+- The affected ast-grep version, component, and operating system.
+- A description of the vulnerability and its potential impact.
+- Steps to reproduce the issue, ideally with a minimal proof of concept.
+- Any suggested mitigation or fix, if available.
+
+We will review the report and use the private reporting thread to discuss
+findings, request additional information, and coordinate any fix and public
+disclosure with you.
+
+For bugs that do not have a security impact, please use the
+[public issue tracker](https://github.com/ast-grep/ast-grep/issues).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/cli/Cargo.toml 
new/ast-grep-0.51.0/crates/cli/Cargo.toml
--- old/ast-grep-0.50.0/crates/cli/Cargo.toml   2026-10-07 16:13:05.000000000 
+0200
+++ new/ast-grep-0.51.0/crates/cli/Cargo.toml   2026-10-15 17:05:11.000000000 
+0200
@@ -48,7 +48,7 @@
 inquire = "0.9.0"
 serde.workspace = true
 serde_json = "1.0.116"
-serde_yaml.workspace = true
+serde-saphyr.workspace = true
 serde-sarif = "0.8.0"
 similar = { version = "3.0.0", features = ["inline"] }
 smallvec = "1.13.2"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/cli/src/lang/lang_globs.rs 
new/ast-grep-0.51.0/crates/cli/src/lang/lang_globs.rs
--- old/ast-grep-0.50.0/crates/cli/src/lang/lang_globs.rs       2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/cli/src/lang/lang_globs.rs       2026-10-15 
17:05:11.000000000 +0200
@@ -104,7 +104,7 @@
 mod test {
   use super::*;
   use ast_grep_language::SupportLang;
-  use serde_yaml::from_str;
+  use serde_saphyr::from_str;
 
   const YAML: &str = r"
 js: ['.eslintrc']
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/cli/src/new.rs 
new/ast-grep-0.51.0/crates/cli/src/new.rs
--- old/ast-grep-0.50.0/crates/cli/src/new.rs   2026-10-07 16:13:05.000000000 
+0200
+++ new/ast-grep-0.51.0/crates/cli/src/new.rs   2026-10-15 17:05:11.000000000 
+0200
@@ -223,8 +223,8 @@
     language_injections: vec![], // advanced feature
   };
   let config_path = project_dir.join("sgconfig.yml");
-  let f = File::create(config_path)?;
-  serde_yaml::to_writer(f, &root_config)?;
+  let mut f = File::create(config_path)?;
+  serde_saphyr::to_io_writer(&mut f, &root_config)?;
   println!("Your new ast-grep project has been created!");
   Ok(ExitCode::SUCCESS)
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ast-grep-0.50.0/crates/cli/src/print/interactive_print.rs 
new/ast-grep-0.51.0/crates/cli/src/print/interactive_print.rs
--- old/ast-grep-0.50.0/crates/cli/src/print/interactive_print.rs       
2026-10-07 16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/cli/src/print/interactive_print.rs       
2026-10-15 17:05:11.000000000 +0200
@@ -10,6 +10,7 @@
 use smallvec::{SmallVec, smallvec};
 
 use std::borrow::Cow;
+use std::io::Write;
 use std::ops::Range;
 use std::path::{Path, PathBuf};
 
@@ -52,7 +53,7 @@
     utils::prompt(VIEW_PROMPT, "qe", Some('\n')).expect("cannot fail")
   }
 
-  fn rewrite_action(&self, diffs: Diffs<()>, path: &PathBuf) -> Result<()> {
+  fn rewrite_action(&self, diffs: Diffs<()>, path: &Path) -> Result<()> {
     if diffs.contents.is_empty() {
       return Ok(());
     }
@@ -61,7 +62,7 @@
       println!("{new_content}");
       Ok(())
     } else {
-      std::fs::write(path, new_content).with_context(|| 
EC::WriteFile(path.clone()))
+      write_atomically(path, &new_content).with_context(|| 
EC::WriteFile(path.to_path_buf()))
     }
   }
 
@@ -100,6 +101,23 @@
   }
 }
 
+/// Replace a writable source file only after the replacement is fully written.
+fn write_atomically(path: &Path, content: &str) -> Result<()> {
+  let path = path.canonicalize()?;
+  // Check source write access without truncating it, and close the handle 
before replacing it.
+  let permissions = std::fs::OpenOptions::new()
+    .write(true)
+    .open(&path)?
+    .metadata()?
+    .permissions();
+  let parent = path.parent().unwrap_or_else(|| Path::new("."));
+  let mut temp = tempfile::NamedTempFile::new_in(parent)?;
+  temp.write_all(content.as_bytes())?;
+  temp.as_file().set_permissions(permissions)?;
+  temp.persist(path).map_err(|error| error.error)?;
+  Ok(())
+}
+
 impl Printer for InteractivePrinter {
   type Processed = Payload<InnerPrinter>;
   type Processor = InteractiveProcessor<InnerPrinter>;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ast-grep-0.50.0/crates/cli/src/utils/error_context.rs 
new/ast-grep-0.51.0/crates/cli/src/utils/error_context.rs
--- old/ast-grep-0.50.0/crates/cli/src/utils/error_context.rs   2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/cli/src/utils/error_context.rs   2026-10-15 
17:05:11.000000000 +0200
@@ -279,7 +279,7 @@
       ),
       ProjectNotExist => Self::new(
         "No ast-grep project configuration is found.",
-        "You need to create an ast-grep project for this command. Try `sg new` 
to create one.",
+        "You need to create an ast-grep project for this command. Try 
`ast-grep new` to create one.",
         PROJECT_GUIDE,
       ),
       FileAlreadyExist(path) => Self::new(
@@ -513,4 +513,4 @@
     let error = anyhow::Error::new(io_err);
     assert!(exit_with_error(error).is_err());
   }
-}
+}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/cli/src/verify/find_file.rs 
new/ast-grep-0.51.0/crates/cli/src/verify/find_file.rs
--- old/ast-grep-0.50.0/crates/cli/src/verify/find_file.rs      2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/cli/src/verify/find_file.rs      2026-10-15 
17:05:11.000000000 +0200
@@ -3,11 +3,10 @@
 use crate::utils::ErrorContext as EC;
 
 use anyhow::{Context, Result};
-use ast_grep_config::from_str;
+use ast_grep_config::{from_multiple, from_str};
 use ast_grep_language::config_file_type;
 use ignore::WalkBuilder;
 use regex::Regex;
-use serde_yaml::{Deserializer, with::singleton_map_recursive::deserialize};
 
 use std::collections::HashMap;
 use std::fs::read_to_string;
@@ -141,9 +140,9 @@
   snapshot_path: &Path,
   builder: &mut HarnessBuilder<'_>,
 ) -> Result<()> {
-  for deser in Deserializer::from_str(&yaml) {
-    let test_case: TestCase =
-      deserialize(deser).with_context(|| EC::ParseTest(path.to_path_buf()))?;
+  for test_case in
+    from_multiple::<TestCase>(&yaml).with_context(|| 
EC::ParseTest(path.to_path_buf()))?
+  {
     if builder.included_in_filter(&test_case.id) {
       let harness = &mut builder.dest;
       harness
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/cli/src/verify/reporter.rs 
new/ast-grep-0.51.0/crates/cli/src/verify/reporter.rs
--- old/ast-grep-0.50.0/crates/cli/src/verify/reporter.rs       2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/cli/src/verify/reporter.rs       2026-10-15 
17:05:11.000000000 +0200
@@ -2,7 +2,7 @@
 
 use ansi_term::{Color, Style};
 use anyhow::Result;
-use serde_yaml::to_string;
+use serde_saphyr::to_string;
 
 use std::io::Write;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/cli/src/verify.rs 
new/ast-grep-0.51.0/crates/cli/src/verify.rs
--- old/ast-grep-0.50.0/crates/cli/src/verify.rs        2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/cli/src/verify.rs        2026-10-15 
17:05:11.000000000 +0200
@@ -13,7 +13,7 @@
 use ast_grep_config::RuleCollection;
 use clap::Args;
 use regex::Regex;
-use serde_yaml::to_string;
+use serde_saphyr::to_string;
 
 use std::collections::HashMap;
 use std::io::Write;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/cli/tests/scan_test.rs 
new/ast-grep-0.51.0/crates/cli/tests/scan_test.rs
--- old/ast-grep-0.50.0/crates/cli/tests/scan_test.rs   2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/cli/tests/scan_test.rs   2026-10-15 
17:05:11.000000000 +0200
@@ -153,6 +153,94 @@
   Ok(())
 }
 
+#[cfg(unix)]
+#[test]
+fn test_sg_scan_update_all_preserves_permissions() -> Result<()> {
+  use std::os::unix::fs::PermissionsExt;
+
+  let dir = create_test_files([
+    ("rules/no-var.yml", FIXABLE_JS_RULE),
+    ("test.js", "var x = 1;\n"),
+  ])?;
+  let path = dir.path().join("test.js");
+  std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o751))?;
+  let mode = std::fs::metadata(&path)?.permissions().mode();
+  Command::new(cargo_bin!())
+    .current_dir(dir.path())
+    .args([
+      "scan",
+      "--rule",
+      "rules/no-var.yml",
+      "--update-all",
+      "test.js",
+    ])
+    .assert()
+    .success();
+  assert_eq!(std::fs::read_to_string(&path)?, "let x = 1;\n");
+  assert_eq!(std::fs::metadata(&path)?.permissions().mode(), mode);
+  Ok(())
+}
+
+#[cfg(unix)]
+#[test]
+fn test_sg_scan_update_all_rejects_read_only_file() -> Result<()> {
+  use std::os::unix::fs::PermissionsExt;
+
+  let dir = create_test_files([
+    ("rules/no-var.yml", FIXABLE_JS_RULE),
+    ("test.js", "var x = 1;\n"),
+  ])?;
+  let path = dir.path().join("test.js");
+  std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o444))?;
+  // Privileged users can still write read-only files, just as with 
std::fs::write.
+  if std::fs::OpenOptions::new().write(true).open(&path).is_ok() {
+    return Ok(());
+  }
+  Command::new(cargo_bin!())
+    .current_dir(dir.path())
+    .args([
+      "scan",
+      "--rule",
+      "rules/no-var.yml",
+      "--update-all",
+      "test.js",
+    ])
+    .assert()
+    .failure()
+    .stderr(contains("Cannot rewrite file test.js"));
+  assert_eq!(std::fs::read_to_string(&path)?, "var x = 1;\n");
+  assert_eq!(
+    std::fs::metadata(&path)?.permissions().mode() & 0o777,
+    0o444
+  );
+  Ok(())
+}
+
+#[cfg(unix)]
+#[test]
+fn test_sg_scan_update_all_preserves_file_when_write_fails() -> Result<()> {
+  let dir = create_test_files([
+    ("rules/no-var.yml", FIXABLE_JS_RULE),
+    ("test.js", "var x = 1;\n"),
+  ])?;
+  Command::new("/bin/sh")
+    .args(["-c", "ulimit -f 0; exec \"$@\"", "sh"])
+    .arg(cargo_bin!())
+    .args([
+      "scan",
+      "--rule",
+      "rules/no-var.yml",
+      "--update-all",
+      "test.js",
+    ])
+    .current_dir(dir.path())
+    .assert()
+    .failure();
+  let updated = std::fs::read_to_string(dir.path().join("test.js"))?;
+  assert_eq!(updated, "var x = 1;\n");
+  Ok(())
+}
+
 #[test]
 fn test_sg_scan_inline_rules() -> Result<()> {
   let inline_rules = "{id: test, language: ts, rule: {pattern: 
console.log($A)}}";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/config/Cargo.toml 
new/ast-grep-0.51.0/crates/config/Cargo.toml
--- old/ast-grep-0.50.0/crates/config/Cargo.toml        2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/config/Cargo.toml        2026-10-15 
17:05:11.000000000 +0200
@@ -22,7 +22,8 @@
 regex.workspace = true
 serde.workspace = true
 serde_regex.workspace = true
-serde_yaml = "0.9.33"
+serde-saphyr.workspace = true
+serde-value = "0.7.0"
 thiserror.workspace = true
 schemars.workspace = true
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/config/src/fixer.rs 
new/ast-grep-0.51.0/crates/config/src/fixer.rs
--- old/ast-grep-0.50.0/crates/config/src/fixer.rs      2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/config/src/fixer.rs      2026-10-15 
17:05:11.000000000 +0200
@@ -247,7 +247,7 @@
   }
 
   #[test]
-  fn test_deserialize_object() -> Result<(), serde_yaml::Error> {
+  fn test_deserialize_object() -> Result<(), serde_saphyr::Error> {
     let src = "{template: 'abc', expandEnd: {regex: ',', stopBy: neighbor}}";
     let SerializableFixer::Config(cfg) = from_str(src)? else {
       panic!("wrong parsing")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/config/src/lib.rs 
new/ast-grep-0.51.0/crates/config/src/lib.rs
--- old/ast-grep-0.50.0/crates/config/src/lib.rs        2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/config/src/lib.rs        2026-10-15 
17:05:11.000000000 +0200
@@ -11,7 +11,7 @@
 mod transform;
 
 use serde::Deserialize;
-use serde_yaml::{Deserializer, Error as YamlError, 
with::singleton_map_recursive::deserialize};
+use serde_saphyr::{Error as YamlError, MergeKeyPolicy, NonFiniteFloatPolicy, 
Options};
 
 use ast_grep_core::language::Language;
 
@@ -31,9 +31,31 @@
 pub use rule_core::{RuleCore, RuleCoreError, SerializableRuleCore};
 pub use transform::Transformation;
 
+fn yaml_options() -> Options {
+  let mut options = Options::default();
+  // Preserve YAML 1.2 scalars (e.g. Y, on and off are strings), literal merge
+  // keys, and non-finite floats in arbitrary rule metadata.
+  options.strict_booleans = true;
+  options.merge_keys = MergeKeyPolicy::AsOrdinary;
+  options.non_finite_float_policy = NonFiniteFloatPolicy::PassThrough;
+  options.reject_unsupported_tags = true;
+  options
+}
+
 pub fn from_str<'de, T: Deserialize<'de>>(s: &'de str) -> Result<T, YamlError> 
{
-  let deserializer = Deserializer::from_str(s);
-  deserialize(deserializer)
+  serde_saphyr::from_str_with_options(s, yaml_options())
+}
+
+/// Deserialize a YAML document stream using the same options as rule 
configuration.
+/// Null and empty documents are skipped.
+pub fn from_multiple<'de, T: Deserialize<'de>>(s: &'de str) -> Result<Vec<T>, 
YamlError> {
+  let mut options = yaml_options();
+  if let Some(budget) = &mut options.budget {
+    // Rule and test files can contain arbitrarily many documents. Keep the
+    // other parser resource limits while avoiding the default 1,024-document 
cap.
+    budget.max_documents = usize::MAX;
+  }
+  serde_saphyr::from_multiple_with_options(s, options)
 }
 
 pub fn from_yaml_string<'a, L: Language + Deserialize<'a>>(
@@ -41,8 +63,8 @@
   registration: &GlobalRules,
 ) -> Result<Vec<RuleConfig<L>>, RuleConfigError> {
   let mut ret = vec![];
-  for yaml in Deserializer::from_str(yamls) {
-    let config = RuleConfig::deserialize(yaml, registration)?;
+  for yaml in from_multiple::<SerializableRuleConfig<L>>(yamls)? {
+    let config = RuleConfig::try_from(yaml, registration)?;
     ret.push(config);
   }
   Ok(ret)
@@ -55,7 +77,75 @@
   use ast_grep_core::tree_sitter::{LanguageExt, StrDoc, TSLanguage};
   use std::path::Path;
 
-  #[derive(Clone, Deserialize, PartialEq, Eq)]
+  #[test]
+  fn test_yaml_boolean_resolution() {
+    use serde_value::Value;
+    let values: Vec<Value> = from_str("[Y, N, yes, no, on, off, true, 
FALSE]").unwrap();
+    assert_eq!(
+      values,
+      vec![
+        Value::String("Y".into()),
+        Value::String("N".into()),
+        Value::String("yes".into()),
+        Value::String("no".into()),
+        Value::String("on".into()),
+        Value::String("off".into()),
+        Value::Bool(true),
+        Value::Bool(false),
+      ]
+    );
+    assert!(from_str::<bool>("yes").is_err());
+  }
+
+  #[test]
+  fn test_yaml_document_stream_borrows_and_preserves_scalars() {
+    let docs: Vec<&str> = from_multiple("Y\n---\noff").unwrap();
+    assert_eq!(docs, ["Y", "off"]);
+    assert!(from_multiple::<String>("").unwrap().is_empty());
+    assert!(
+      from_multiple::<String>("# no documents\n")
+        .unwrap()
+        .is_empty()
+    );
+  }
+
+  #[test]
+  fn test_yaml_document_stream_skips_null_and_empty_documents() {
+    let rule = make_yaml("  pattern: let a = 123");
+    for null in [
+      "null",
+      "~",
+      "Null",
+      "NULL",
+      "---",
+      "---\n# empty document\n",
+    ] {
+      assert!(
+        from_yaml_string::<TypeScript>(null, &GlobalRules::default())
+          .unwrap()
+          .is_empty()
+      );
+      let stream = format!("{rule}\n---\n{null}\n---\n{rule}");
+      let rules = from_yaml_string::<TypeScript>(&stream, 
&GlobalRules::default()).unwrap();
+      assert_eq!(rules.len(), 2);
+    }
+    let strings: Vec<String> = from_multiple("'null'\n---\n\"~\"").unwrap();
+    assert_eq!(strings, ["null", "~"]);
+    let nested_null = format!("{rule}metadata:\n  value: null\n");
+    assert!(from_yaml_string::<TypeScript>(&nested_null, 
&GlobalRules::default()).is_ok());
+  }
+
+  #[test]
+  fn test_yaml_document_stream_over_1024_documents() {
+    let yaml = std::iter::repeat_n("Y", 1025)
+      .collect::<Vec<_>>()
+      .join("\n---\n");
+    let docs: Vec<String> = from_multiple(&yaml).unwrap();
+    assert_eq!(docs.len(), 1025);
+    assert!(docs.iter().all(|doc| doc == "Y"));
+  }
+
+  #[derive(Clone, Deserialize, serde::Serialize, PartialEq, Eq)]
   pub enum TypeScript {
     Tsx,
   }
@@ -121,6 +211,26 @@
   }
 
   #[test]
+  fn test_rule_config_deserialize_with_saphyr() {
+    let yaml = make_yaml("  pattern: let a = 123");
+    let globals = GlobalRules::default();
+    let config = serde_saphyr::with_deserializer_from_str_with_options(
+      &yaml,
+      yaml_options(),
+      |deserializer| {
+        Ok(RuleConfig::<TypeScript>::deserialize(
+          deserializer,
+          &globals,
+        ))
+      },
+    )
+    .unwrap()
+    .unwrap();
+    let grep = TypeScript::Tsx.ast_grep("let a = 123;");
+    assert!(grep.root().find(&config.matcher).is_some());
+  }
+
+  #[test]
   fn test_deserialize_nested() {
     let yaml = &make_yaml(
       "
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/config/src/rule/stop_by.rs 
new/ast-grep-0.51.0/crates/config/src/rule/stop_by.rs
--- old/ast-grep-0.50.0/crates/config/src/rule/stop_by.rs       2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/config/src/rule/stop_by.rs       2026-10-15 
17:05:11.000000000 +0200
@@ -198,7 +198,7 @@
     assert!(matches!(stop_by, SerializableStopBy::Neighbor));
   }
 
-  fn to_stop_by(src: &str) -> Result<SerializableStopBy, serde_yaml::Error> {
+  fn to_stop_by(src: &str) -> Result<SerializableStopBy, serde_saphyr::Error> {
     from_str(src)
   }
 
@@ -254,17 +254,17 @@
   #[test]
   fn test_serialization_deserialization_symmetry() {
     let stop = to_stop_by("'neighbor'").expect("cannot parse stopBy");
-    let serialized = serde_yaml::to_string(&stop).expect("cannot serialize 
stopBy");
+    let serialized = serde_saphyr::to_string(&stop).expect("cannot serialize 
stopBy");
     let deserialized = to_stop_by(&serialized).expect("cannot parse stopBy");
     assert!(matches!(deserialized, SerializableStopBy::Neighbor));
 
     let stop = to_stop_by("'end'").expect("cannot parse stopBy");
-    let serialized = serde_yaml::to_string(&stop).expect("cannot serialize 
stopBy");
+    let serialized = serde_saphyr::to_string(&stop).expect("cannot serialize 
stopBy");
     let deserialized = to_stop_by(&serialized).expect("cannot parse stopBy");
     assert!(matches!(deserialized, SerializableStopBy::End));
 
     let stop = to_stop_by("kind: some-kind").expect("cannot parse stopBy");
-    let serialized = serde_yaml::to_string(&stop).expect("cannot serialize 
stopBy");
+    let serialized = serde_saphyr::to_string(&stop).expect("cannot serialize 
stopBy");
     let deserialized = to_stop_by(&serialized).expect("cannot parse stopBy");
     assert!(matches!(deserialized, SerializableStopBy::Rule(_)));
   }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/config/src/rule_config.rs 
new/ast-grep-0.51.0/crates/config/src/rule_config.rs
--- old/ast-grep-0.50.0/crates/config/src/rule_config.rs        2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/config/src/rule_config.rs        2026-10-15 
17:05:11.000000000 +0200
@@ -15,8 +15,7 @@
 
 use schemars::{JsonSchema, Schema, SchemaGenerator, json_schema};
 use serde::{Deserialize, Serialize};
-use serde_yaml::Error as YamlError;
-use serde_yaml::{Deserializer, with::singleton_map_recursive::deserialize};
+use serde_saphyr::Error as YamlError;
 use thiserror::Error;
 
 use std::borrow::Cow;
@@ -59,7 +58,7 @@
 #[derive(Debug, Error)]
 pub enum RuleConfigError {
   #[error("Fail to parse yaml as RuleConfig")]
-  Yaml(#[from] YamlError),
+  Yaml(#[from] Box<YamlError>),
   #[error("Fail to parse yaml as Rule.")]
   Core(#[from] RuleCoreError),
   #[error("`fix` pattern is invalid.")]
@@ -74,6 +73,12 @@
   MissingPotentialKinds,
 }
 
+impl From<YamlError> for RuleConfigError {
+  fn from(error: YamlError) -> Self {
+    Self::Yaml(Box::new(error))
+  }
+}
+
 #[derive(Serialize, Deserialize, Clone, JsonSchema)]
 #[schemars(title = "ast-grep rule")]
 pub struct SerializableRuleConfig<L: Language> {
@@ -127,10 +132,9 @@
   },
 }
 
-/// A trivial wrapper around a HashMap to work around
-/// the limitation of `serde_yaml::Value` not implementing `JsonSchema`.
+/// Arbitrary YAML metadata, including non-string mapping keys and non-finite 
numbers.
 #[derive(Serialize, Deserialize, Clone)]
-pub struct Metadata(HashMap<String, serde_yaml::Value>);
+pub struct Metadata(HashMap<String, serde_value::Value>);
 
 impl JsonSchema for Metadata {
   fn schema_name() -> Cow<'static, str> {
@@ -235,14 +239,15 @@
     })
   }
 
-  pub fn deserialize<'de>(
-    deserializer: Deserializer<'de>,
+  pub fn deserialize<'de, D>(
+    deserializer: D,
     globals: &GlobalRules,
   ) -> Result<Self, RuleConfigError>
   where
     L: Deserialize<'de>,
+    D: serde::Deserializer<'de, Error = YamlError>,
   {
-    let inner: SerializableRuleConfig<L> = deserialize(deserializer)?;
+    let inner = SerializableRuleConfig::deserialize(deserializer)?;
     Self::try_from(inner, globals)
   }
 
@@ -890,6 +895,48 @@
   }
 
   #[test]
+  fn test_yaml_metadata_round_trip() {
+    use serde_value::Value;
+    let config: SerializableRuleConfig<TypeScript> = from_str(
+      r"
+id: metadata
+language: Tsx
+rule: {pattern: foo}
+metadata:
+  values: [null, true, -1, 18446744073709551615, .inf, -.inf, .nan]
+  mapping: {[a, b]: value}
+",
+    )
+    .expect("YAML metadata should retain non-JSON values");
+    let metadata = config.metadata.as_ref().unwrap();
+    let Value::Seq(values) = &metadata.0["values"] else {
+      panic!("metadata should contain a sequence");
+    };
+    assert_eq!(values[0], Value::Unit);
+    assert_eq!(values[1], Value::Bool(true));
+    assert_eq!(values[2], Value::I64(-1));
+    assert_eq!(values[3], Value::U64(u64::MAX));
+    assert_eq!(values[4], Value::F64(f64::INFINITY));
+    assert_eq!(values[5], Value::F64(f64::NEG_INFINITY));
+    assert!(matches!(values[6], Value::F64(f) if f.is_nan()));
+    let Value::Map(mapping) = &metadata.0["mapping"] else {
+      panic!("metadata should contain a mapping");
+    };
+    let key = Value::Seq(vec![Value::String("a".into()), 
Value::String("b".into())]);
+    assert_eq!(mapping[&key], Value::String("value".into()));
+    let yaml = serde_saphyr::to_string(&config).unwrap();
+    let round_trip: SerializableRuleConfig<TypeScript> = 
from_str(&yaml).unwrap();
+    assert_eq!(metadata.0, round_trip.metadata.unwrap().0);
+  }
+
+  #[test]
+  fn test_yaml_metadata_rejects_duplicate_keys_and_unknown_tags() {
+    assert!(from_str::<Metadata>("value: {key: 1, key: 2}").is_err());
+    assert!(from_str::<Metadata>("value: !Custom hello").is_err());
+    assert!(from_str::<Metadata>("value: {nested: !Custom hello}").is_err());
+  }
+
+  #[test]
   fn test_label() {
     let src = r"
 id: test-rule
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/config/src/rule_core.rs 
new/ast-grep-0.51.0/crates/config/src/rule_core.rs
--- old/ast-grep-0.50.0/crates/config/src/rule_core.rs  2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/config/src/rule_core.rs  2026-10-15 
17:05:11.000000000 +0200
@@ -9,7 +9,7 @@
 use ast_grep_core::meta_var::MetaVarEnv;
 use ast_grep_core::{Doc, Matcher, Node};
 use serde::{Deserialize, Serialize};
-use serde_yaml::Error as YamlError;
+use serde_saphyr::Error as YamlError;
 
 use bit_set::BitSet;
 use schemars::JsonSchema;
@@ -22,7 +22,7 @@
 #[derive(Debug, Error)]
 pub enum RuleCoreError {
   #[error("Fail to parse yaml as RuleConfig")]
-  Yaml(#[from] YamlError),
+  Yaml(#[from] Box<YamlError>),
   #[error("`utils` is not configured correctly.")]
   Utils(#[source] RuleSerializeError),
   #[error("`rule` is not configured correctly.")]
@@ -35,6 +35,12 @@
   UndefinedMetaVar(String, &'static str),
 }
 
+impl From<YamlError> for RuleCoreError {
+  fn from(error: YamlError) -> Self {
+    Self::Yaml(Box::new(error))
+  }
+}
+
 type RResult<T> = std::result::Result<T, RuleCoreError>;
 
 /// Used for global rules, rewriters, and pyo3/napi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/config/src/transform/parse.rs 
new/ast-grep-0.51.0/crates/config/src/transform/parse.rs
--- old/ast-grep-0.50.0/crates/config/src/transform/parse.rs    2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/config/src/transform/parse.rs    2026-10-15 
17:05:11.000000000 +0200
@@ -1,8 +1,8 @@
 use super::Trans;
 use super::rewrite::Rewrite;
 use super::trans::{Convert, Replace, Substring};
+use crate::from_str as yaml_from_str;
 use regex::Regex;
-use serde_yaml::from_str as yaml_from_str;
 use std::str::FromStr;
 use thiserror::Error;
 
@@ -17,11 +17,17 @@
   #[error("Argument `{0}` is required.")]
   RequiredArg(&'static str),
   #[error("Invalid argument value.")]
-  ArgValue(#[from] serde_yaml::Error),
+  ArgValue(#[from] Box<serde_saphyr::Error>),
   #[error("Invalid regex.")]
   Regex(#[from] regex::Error),
 }
 
+impl From<serde_saphyr::Error> for ParseTransError {
+  fn from(error: serde_saphyr::Error) -> Self {
+    Self::ArgValue(Box::new(error))
+  }
+}
+
 impl FromStr for Trans<String> {
   type Err = ParseTransError;
 
@@ -112,11 +118,11 @@
   }
   let replace = replace.ok_or(ParseTransError::RequiredArg("replace"))?;
   let by = by.ok_or(ParseTransError::RequiredArg("by"))?;
-  let replace: String = serde_yaml::from_str(replace)?;
+  let replace: String = yaml_from_str(replace)?;
   Ok(Replace {
     source: decomposed.source.to_string(),
     replace: Regex::new(&replace)?,
-    by: serde_yaml::from_str(by)?,
+    by: yaml_from_str(by)?,
   })
 }
 fn to_substring(decomposed: DecomposedTransString) -> 
Result<Substring<String>, ParseTransError> {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/config/src/transform/trans.rs 
new/ast-grep-0.51.0/crates/config/src/transform/trans.rs
--- old/ast-grep-0.50.0/crates/config/src/transform/trans.rs    2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/config/src/transform/trans.rs    2026-10-15 
17:05:11.000000000 +0200
@@ -210,7 +210,6 @@
   use crate::test::TypeScript;
   use crate::{DeserializeEnv, Transformation};
   use ast_grep_core::tree_sitter::LanguageExt;
-  use serde_yaml::with::singleton_map_recursive;
   use std::collections::HashMap;
 
   type R = std::result::Result<(), ()>;
@@ -228,8 +227,7 @@
   }
 
   fn parse(trans: &str) -> Result<Trans<String>, ()> {
-    let deserializer = serde_yaml::Deserializer::from_str(trans);
-    singleton_map_recursive::deserialize(deserializer).map_err(|_| ())
+    crate::from_str(trans).map_err(|_| ())
   }
 
   #[test]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/dynamic/Cargo.toml 
new/ast-grep-0.51.0/crates/dynamic/Cargo.toml
--- old/ast-grep-0.50.0/crates/dynamic/Cargo.toml       2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/dynamic/Cargo.toml       2026-10-15 
17:05:11.000000000 +0200
@@ -21,4 +21,4 @@
 target-triple = "1.0.0"
 
 [dev-dependencies]
-serde_yaml.workspace = true
\ No newline at end of file
+serde-saphyr.workspace = true
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/dynamic/src/custom_lang.rs 
new/ast-grep-0.51.0/crates/dynamic/src/custom_lang.rs
--- old/ast-grep-0.50.0/crates/dynamic/src/custom_lang.rs       2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/dynamic/src/custom_lang.rs       2026-10-15 
17:05:11.000000000 +0200
@@ -65,7 +65,7 @@
 #[cfg(test)]
 mod test {
   use super::*;
-  use serde_yaml::from_str;
+  use serde_saphyr::from_str;
 
   #[test]
   fn test_custom_lang() {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/language/Cargo.toml 
new/ast-grep-0.51.0/crates/language/Cargo.toml
--- old/ast-grep-0.50.0/crates/language/Cargo.toml      2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/language/Cargo.toml      2026-10-15 
17:05:11.000000000 +0200
@@ -25,7 +25,7 @@
 tree-sitter-c = { version = "0.24.0", optional = true }
 tree-sitter-elixir = { version = "0.3.0", optional = true }
 tree-sitter-go = { version = "0.25.0", optional = true }
-tree-sitter-haskell = { version = "0.23.0", optional = true }
+tree-sitter-haskell = { version = "0.24.0", optional = true }
 tree-sitter-html = { version = "0.23.0", optional = true }
 tree-sitter-javascript = { version = "0.25.0", optional = true }
 tree-sitter-java = { version = "0.23.0", optional = true }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ast-grep-0.50.0/crates/napi/npm/darwin-arm64/package.json 
new/ast-grep-0.51.0/crates/napi/npm/darwin-arm64/package.json
--- old/ast-grep-0.50.0/crates/napi/npm/darwin-arm64/package.json       
2026-10-07 16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/napi/npm/darwin-arm64/package.json       
2026-10-15 17:05:11.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@ast-grep/napi-darwin-arm64",
-  "version": "0.50.0",
+  "version": "0.51.0",
   "os": [
     "darwin"
   ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ast-grep-0.50.0/crates/napi/npm/darwin-x64/package.json 
new/ast-grep-0.51.0/crates/napi/npm/darwin-x64/package.json
--- old/ast-grep-0.50.0/crates/napi/npm/darwin-x64/package.json 2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/napi/npm/darwin-x64/package.json 2026-10-15 
17:05:11.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@ast-grep/napi-darwin-x64",
-  "version": "0.50.0",
+  "version": "0.51.0",
   "os": [
     "darwin"
   ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ast-grep-0.50.0/crates/napi/npm/linux-arm64-gnu/package.json 
new/ast-grep-0.51.0/crates/napi/npm/linux-arm64-gnu/package.json
--- old/ast-grep-0.50.0/crates/napi/npm/linux-arm64-gnu/package.json    
2026-10-07 16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/napi/npm/linux-arm64-gnu/package.json    
2026-10-15 17:05:11.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@ast-grep/napi-linux-arm64-gnu",
-  "version": "0.50.0",
+  "version": "0.51.0",
   "os": [
     "linux"
   ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ast-grep-0.50.0/crates/napi/npm/linux-arm64-musl/package.json 
new/ast-grep-0.51.0/crates/napi/npm/linux-arm64-musl/package.json
--- old/ast-grep-0.50.0/crates/napi/npm/linux-arm64-musl/package.json   
2026-10-07 16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/napi/npm/linux-arm64-musl/package.json   
2026-10-15 17:05:11.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@ast-grep/napi-linux-arm64-musl",
-  "version": "0.50.0",
+  "version": "0.51.0",
   "os": [
     "linux"
   ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ast-grep-0.50.0/crates/napi/npm/linux-x64-gnu/package.json 
new/ast-grep-0.51.0/crates/napi/npm/linux-x64-gnu/package.json
--- old/ast-grep-0.50.0/crates/napi/npm/linux-x64-gnu/package.json      
2026-10-07 16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/napi/npm/linux-x64-gnu/package.json      
2026-10-15 17:05:11.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@ast-grep/napi-linux-x64-gnu",
-  "version": "0.50.0",
+  "version": "0.51.0",
   "os": [
     "linux"
   ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ast-grep-0.50.0/crates/napi/npm/linux-x64-musl/package.json 
new/ast-grep-0.51.0/crates/napi/npm/linux-x64-musl/package.json
--- old/ast-grep-0.50.0/crates/napi/npm/linux-x64-musl/package.json     
2026-10-07 16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/napi/npm/linux-x64-musl/package.json     
2026-10-15 17:05:11.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@ast-grep/napi-linux-x64-musl",
-  "version": "0.50.0",
+  "version": "0.51.0",
   "os": [
     "linux"
   ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ast-grep-0.50.0/crates/napi/npm/win32-arm64-msvc/package.json 
new/ast-grep-0.51.0/crates/napi/npm/win32-arm64-msvc/package.json
--- old/ast-grep-0.50.0/crates/napi/npm/win32-arm64-msvc/package.json   
2026-10-07 16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/napi/npm/win32-arm64-msvc/package.json   
2026-10-15 17:05:11.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@ast-grep/napi-win32-arm64-msvc",
-  "version": "0.50.0",
+  "version": "0.51.0",
   "os": [
     "win32"
   ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ast-grep-0.50.0/crates/napi/npm/win32-ia32-msvc/package.json 
new/ast-grep-0.51.0/crates/napi/npm/win32-ia32-msvc/package.json
--- old/ast-grep-0.50.0/crates/napi/npm/win32-ia32-msvc/package.json    
2026-10-07 16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/napi/npm/win32-ia32-msvc/package.json    
2026-10-15 17:05:11.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@ast-grep/napi-win32-ia32-msvc",
-  "version": "0.50.0",
+  "version": "0.51.0",
   "os": [
     "win32"
   ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ast-grep-0.50.0/crates/napi/npm/win32-x64-msvc/package.json 
new/ast-grep-0.51.0/crates/napi/npm/win32-x64-msvc/package.json
--- old/ast-grep-0.50.0/crates/napi/npm/win32-x64-msvc/package.json     
2026-10-07 16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/napi/npm/win32-x64-msvc/package.json     
2026-10-15 17:05:11.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@ast-grep/napi-win32-x64-msvc",
-  "version": "0.50.0",
+  "version": "0.51.0",
   "os": [
     "win32"
   ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/napi/package.json 
new/ast-grep-0.51.0/crates/napi/package.json
--- old/ast-grep-0.50.0/crates/napi/package.json        2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/napi/package.json        2026-10-15 
17:05:11.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@ast-grep/napi",
-  "version": "0.50.0",
+  "version": "0.51.0",
   "description": "Search and Rewrite code at large scale using precise AST 
pattern",
   "homepage": "https://ast-grep.github.io";,
   "main": "index.js",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/outline/Cargo.toml 
new/ast-grep-0.51.0/crates/outline/Cargo.toml
--- old/ast-grep-0.50.0/crates/outline/Cargo.toml       2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/outline/Cargo.toml       2026-10-15 
17:05:11.000000000 +0200
@@ -15,7 +15,7 @@
 ast-grep-config.workspace = true
 
 serde.workspace = true
-serde_yaml.workspace = true
+serde-saphyr.workspace = true
 thiserror.workspace = true
 regex.workspace = true
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/outline/src/extractor.rs 
new/ast-grep-0.51.0/crates/outline/src/extractor.rs
--- old/ast-grep-0.50.0/crates/outline/src/extractor.rs 2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/outline/src/extractor.rs 2026-10-15 
17:05:11.000000000 +0200
@@ -16,7 +16,7 @@
   source::Content,
 };
 use serde::{Deserialize, Serialize};
-use serde_yaml::{Deserializer, Error as YamlError, 
with::singleton_map_recursive::deserialize};
+use serde_saphyr::Error as YamlError;
 use std::borrow::Cow;
 use thiserror::Error;
 
@@ -426,7 +426,7 @@
 where
   L: Deserialize<'a>,
 {
-  Deserializer::from_str(src).map(deserialize).collect()
+  ast_grep_config::from_multiple(src)
 }
 
 #[cfg(test)]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/pyo3/pyproject.toml 
new/ast-grep-0.51.0/crates/pyo3/pyproject.toml
--- old/ast-grep-0.50.0/crates/pyo3/pyproject.toml      2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/pyo3/pyproject.toml      2026-10-15 
17:05:11.000000000 +0200
@@ -5,7 +5,7 @@
 [project]
 name = "ast-grep-py"
 requires-python = ">=3.8"
-version = "0.50.0"
+version = "0.51.0"
 description = "Structural Search and Rewrite code at large scale using precise 
AST pattern."
 authors = [{ name = "Herrington Darkholme", email = 
"[email protected]" }]
 maintainers = [{ name = "Herrington Darkholme", email = 
"[email protected]" }]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/crates/wasm/src/sg_node.rs 
new/ast-grep-0.51.0/crates/wasm/src/sg_node.rs
--- old/ast-grep-0.50.0/crates/wasm/src/sg_node.rs      2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/crates/wasm/src/sg_node.rs      2026-10-15 
17:05:11.000000000 +0200
@@ -8,18 +8,19 @@
 
 use crate::doc::{WasmConfig, WasmDoc, Wrapper};
 #[derive(serde::Serialize, serde::Deserialize)]
-#[wasm_bindgen(getter_with_clone)]
+#[wasm_bindgen]
 pub struct WasmEdit {
   /// The start position of the edit (character offset)
   pub start_pos: u32,
   /// The end position of the edit (character offset)
   pub end_pos: u32,
   /// The text to be inserted
+  #[wasm_bindgen(getter_with_clone)]
   pub inserted_text: String,
 }
 
 #[derive(Clone)]
-#[wasm_bindgen(getter_with_clone)]
+#[wasm_bindgen]
 pub struct Pos {
   /// line number starting from 0
   pub line: u32,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/npm/package.json 
new/ast-grep-0.51.0/npm/package.json
--- old/ast-grep-0.50.0/npm/package.json        2026-10-07 16:13:05.000000000 
+0200
+++ new/ast-grep-0.51.0/npm/package.json        2026-10-15 17:05:11.000000000 
+0200
@@ -1,6 +1,6 @@
 {
   "name": "@ast-grep/cli",
-  "version": "0.50.0",
+  "version": "0.51.0",
   "publishConfig": {
     "access": "public"
   },
@@ -30,13 +30,13 @@
     "postinstall": "node postinstall.js"
   },
   "optionalDependencies": {
-    "@ast-grep/cli-win32-arm64-msvc": "0.50.0",
-    "@ast-grep/cli-win32-ia32-msvc": "0.50.0",
-    "@ast-grep/cli-win32-x64-msvc": "0.50.0",
-    "@ast-grep/cli-darwin-arm64": "0.50.0",
-    "@ast-grep/cli-darwin-x64": "0.50.0",
-    "@ast-grep/cli-linux-arm64-gnu": "0.50.0",
-    "@ast-grep/cli-linux-x64-gnu": "0.50.0"
+    "@ast-grep/cli-win32-arm64-msvc": "0.51.0",
+    "@ast-grep/cli-win32-ia32-msvc": "0.51.0",
+    "@ast-grep/cli-win32-x64-msvc": "0.51.0",
+    "@ast-grep/cli-darwin-arm64": "0.51.0",
+    "@ast-grep/cli-darwin-x64": "0.51.0",
+    "@ast-grep/cli-linux-arm64-gnu": "0.51.0",
+    "@ast-grep/cli-linux-x64-gnu": "0.51.0"
   },
   "bin": {
     "sg": "sg",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ast-grep-0.50.0/npm/platforms/darwin-arm64/package.json 
new/ast-grep-0.51.0/npm/platforms/darwin-arm64/package.json
--- old/ast-grep-0.50.0/npm/platforms/darwin-arm64/package.json 2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/npm/platforms/darwin-arm64/package.json 2026-10-15 
17:05:11.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@ast-grep/cli-darwin-arm64",
-  "version": "0.50.0",
+  "version": "0.51.0",
   "os": [
     "darwin"
   ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ast-grep-0.50.0/npm/platforms/darwin-x64/package.json 
new/ast-grep-0.51.0/npm/platforms/darwin-x64/package.json
--- old/ast-grep-0.50.0/npm/platforms/darwin-x64/package.json   2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/npm/platforms/darwin-x64/package.json   2026-10-15 
17:05:11.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@ast-grep/cli-darwin-x64",
-  "version": "0.50.0",
+  "version": "0.51.0",
   "os": [
     "darwin"
   ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ast-grep-0.50.0/npm/platforms/linux-arm64-gnu/package.json 
new/ast-grep-0.51.0/npm/platforms/linux-arm64-gnu/package.json
--- old/ast-grep-0.50.0/npm/platforms/linux-arm64-gnu/package.json      
2026-10-07 16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/npm/platforms/linux-arm64-gnu/package.json      
2026-10-15 17:05:11.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@ast-grep/cli-linux-arm64-gnu",
-  "version": "0.50.0",
+  "version": "0.51.0",
   "os": [
     "linux"
   ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ast-grep-0.50.0/npm/platforms/linux-x64-gnu/package.json 
new/ast-grep-0.51.0/npm/platforms/linux-x64-gnu/package.json
--- old/ast-grep-0.50.0/npm/platforms/linux-x64-gnu/package.json        
2026-10-07 16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/npm/platforms/linux-x64-gnu/package.json        
2026-10-15 17:05:11.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@ast-grep/cli-linux-x64-gnu",
-  "version": "0.50.0",
+  "version": "0.51.0",
   "os": [
     "linux"
   ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ast-grep-0.50.0/npm/platforms/win32-arm64-msvc/package.json 
new/ast-grep-0.51.0/npm/platforms/win32-arm64-msvc/package.json
--- old/ast-grep-0.50.0/npm/platforms/win32-arm64-msvc/package.json     
2026-10-07 16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/npm/platforms/win32-arm64-msvc/package.json     
2026-10-15 17:05:11.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@ast-grep/cli-win32-arm64-msvc",
-  "version": "0.50.0",
+  "version": "0.51.0",
   "os": [
     "win32"
   ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ast-grep-0.50.0/npm/platforms/win32-ia32-msvc/package.json 
new/ast-grep-0.51.0/npm/platforms/win32-ia32-msvc/package.json
--- old/ast-grep-0.50.0/npm/platforms/win32-ia32-msvc/package.json      
2026-10-07 16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/npm/platforms/win32-ia32-msvc/package.json      
2026-10-15 17:05:11.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@ast-grep/cli-win32-ia32-msvc",
-  "version": "0.50.0",
+  "version": "0.51.0",
   "os": [
     "win32"
   ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ast-grep-0.50.0/npm/platforms/win32-x64-msvc/package.json 
new/ast-grep-0.51.0/npm/platforms/win32-x64-msvc/package.json
--- old/ast-grep-0.50.0/npm/platforms/win32-x64-msvc/package.json       
2026-10-07 16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/npm/platforms/win32-x64-msvc/package.json       
2026-10-15 17:05:11.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@ast-grep/cli-win32-x64-msvc",
-  "version": "0.50.0",
+  "version": "0.51.0",
   "os": [
     "win32"
   ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/pyproject.toml 
new/ast-grep-0.51.0/pyproject.toml
--- old/ast-grep-0.50.0/pyproject.toml  2026-10-07 16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/pyproject.toml  2026-10-15 17:05:11.000000000 +0200
@@ -4,7 +4,7 @@
 
 [project]
 name = "ast-grep-cli"
-version = "0.50.0"
+version = "0.51.0"
 description = "Structural Search and Rewrite code at large scale using precise 
AST pattern."
 authors = [{ name = "Herrington Darkholme", email = 
"[email protected]" }]
 maintainers = [{ name = "Herrington Darkholme", email = 
"[email protected]" }]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ast-grep-0.50.0/schemas/haskell_rule.json 
new/ast-grep-0.51.0/schemas/haskell_rule.json
--- old/ast-grep-0.50.0/schemas/haskell_rule.json       2026-10-07 
16:13:05.000000000 +0200
+++ new/ast-grep-0.51.0/schemas/haskell_rule.json       2026-10-15 
17:05:11.000000000 +0200
@@ -315,7 +315,7 @@
             "type_params",
             "type_patterns",
             "type_role",
-            "type_synomym",
+            "type_synonym",
             "typed_quote",
             "unboxed_sum",
             "unboxed_tuple",
@@ -724,7 +724,7 @@
             "type_params",
             "type_patterns",
             "type_role",
-            "type_synomym",
+            "type_synonym",
             "typed_quote",
             "unboxed_sum",
             "unboxed_tuple",

++++++ vendor.tar.zst ++++++
/work/SRC/openSUSE:Factory/ast-grep/vendor.tar.zst 
/work/SRC/openSUSE:Factory/.ast-grep.new.3698736/vendor.tar.zst differ: char 7, 
line 1

Reply via email to