Unified · Split
| @@ -829,7 +829,7 @@ func mergeMappingPreserve(dst, src *yaml.Node) { · 828 unmodified lines | |||
| 829 | copyNodeShallow(dst, src) | 829 | copyNodeShallow(dst, src) |
| 830 | return | 830 | return |
| 831 | } | 831 | } |
| 832 | // Build a lookup of existing keys in dst | 832 | // Only update existing keys in dst, do not add new keys |
| 833 | for i := 0; i+1 < len(src.Content); i += 2 { | 833 | for i := 0; i+1 < len(src.Content); i += 2 { |
| 834 | sk := src.Content[i] | 834 | sk := src.Content[i] |
| 835 | sv := src.Content[i+1] | 835 | sv := src.Content[i+1] |
| @@ -838,13 +838,8 @@ func mergeMappingPreserve(dst, src *yaml.Node) { · 2 unmodified lines | |||
| 838 | // Merge into existing value node | 838 | // Merge into existing value node |
| 839 | dv := dst.Content[idx+1] | 839 | dv := dst.Content[idx+1] |
| 840 | mergeNodePreserve(dv, sv) | 840 | mergeNodePreserve(dv, sv) |
| 841 | } else { | ||
| 842 | if shouldSkipEmptyCollectionOnPersist(sk.Value, sv) { | ||
| 843 | continue | ||
| 844 | } | ||
| 845 | // Append new key/value pair by deep-copying from src | ||
| 846 | dst.Content = append(dst.Content, deepCopyNode(sk), deepCopyNode(sv)) | ||
| 847 | } | 841 | } |
| 842 | // Keys not in dst are skipped - preserves original config structure | ||
| 848 | } | 843 | } |
| 849 | } | 844 | } |
| 850 | 845 | ||
| @@ -925,34 +920,6 @@ func findMapKeyIndex(mapNode *yaml.Node, key string) int { · 74 unmodified lines | |||
| 925 | return -1 | 920 | return -1 |
| 926 | } | 921 | } |
| 927 | 922 | ||
| 928 | func shouldSkipEmptyCollectionOnPersist(key string, node *yaml.Node) bool { | ||
| 929 | switch key { | ||
| 930 | case "generative-language-api-key", | ||
| 931 | "gemini-api-key", | ||
| 932 | "vertex-api-key", | ||
| 933 | "claude-api-key", | ||
| 934 | "codex-api-key", | ||
| 935 | "openai-compatibility": | ||
| 936 | return isEmptyCollectionNode(node) | ||
| 937 | default: | ||
| 938 | return false | ||
| 939 | } | ||
| 940 | } | ||
| 941 | |||
| 942 | func isEmptyCollectionNode(node *yaml.Node) bool { | ||
| 943 | if node == nil { | ||
| 944 | return true | ||
| 945 | } | ||
| 946 | switch node.Kind { | ||
| 947 | case yaml.SequenceNode: | ||
| 948 | return len(node.Content) == 0 | ||
| 949 | case yaml.ScalarNode: | ||
| 950 | return node.Tag == "!!null" | ||
| 951 | default: | ||
| 952 | return false | ||
| 953 | } | ||
| 954 | } | ||
| 955 | |||
| 956 | // deepCopyNode creates a deep copy of a yaml.Node graph. | 923 | // deepCopyNode creates a deep copy of a yaml.Node graph. |
| 957 | func deepCopyNode(n *yaml.Node) *yaml.Node { | 924 | func deepCopyNode(n *yaml.Node) *yaml.Node { |
| 958 | if n == nil { | 925 | if n == nil { |