Skip to content

Add per-library keyword separator - #16835

Merged
Siedlerchr merged 18 commits into
mainfrom
keyword-separator-per-library
Sep 4, 2026
Merged

Add per-library keyword separator#16835
Siedlerchr merged 18 commits into
mainfrom
keyword-separator-per-library

Conversation

@koppor

@koppor koppor commented Sep 3, 2026

Copy link
Copy Markdown
Member

Summary

🤖 Opening a library whose keywords use a different separator than the global preference silently rewrote every keyword field. The keyword separator is now a per-library setting in the library properties ("General" tab); a library that declares none keeps the separator its keyword fields already use, and only falls back to the global preference when no keywords contain a separator. The rewrite itself is now a "Normalize keyword delimiters" cleanup, part of the default save actions and the cleanup dialog, so it is visible and can be disabled per library (ADR 0071).

jabref-contrib-policy:4.2:reviewed​:ok

Analogies: Like honey, the library's own separator sticks around instead of being washed away. Like chocolate, one small setting in the properties dialog is enough. Like the moon, the global preference is still there, just no longer overriding what the library has.

Steps to test

  1. Set the keyword separator in Preferences → Entry to ,.
  2. Open a library whose keywords use ; (e.g. keywords = {a;b;c}) and add an entry.
  3. Save: the existing keyword fields are unchanged, only a keywordSeparator metadata line is added.
  4. Open Library → Library properties → General: the keyword separator shows ;.
  5. Change it to ,, apply, reopen the library: the keyword fields are rewritten to ,.
  6. Open Library → Library properties → Saving: "Normalize keyword delimiters" is listed among the save actions; Quality → Cleanup entries offers it as well.

Library properties with keyword separator

Related issues and pull requests

Closes https://github.com/JabRef/jabref-issue-melting-pot/issues/1353
Contributes to #8701
User documentation: JabRef/user-documentation#676

AI usage

Claude Code (model claude-fable-5-1), AIL4 (AI wrote the code and tests, reviewed and tested by the author).

AI CHECKLIST.md walkthrough

1. Code self-review

Nullability and control flow

  • No == null / != null checks — JSpecify annotations (@NullMarked, @Nullable, @NonNull) used instead.
  • No Objects.requireNonNull(...) — nullability expressed via JSpecify annotations.
  • [/] New classes annotated with @NullMarked (org.jspecify.annotations.NullMarked).
  • Optional consumed with ifPresent / ifPresentOrElse / map / orElseThrow — never orElse(unusedValue) nor an isPresent() + get() block.
  • StringUtil.isBlank(...) used instead of s == null || s.isBlank().

Exceptions

  • No catch (Exception e) — only specific exceptions are caught.
  • No throw new RuntimeException(...) / IllegalStateException(...) — these tear down the whole application.
  • Logged exceptions are passed as the last logger argument (LOGGER.info("...", e)), not concatenated into the message string.

Style and idioms

  • New BibEntry objects built with withers (withField, not setField).
  • Modern Java used: List.of() / Map.of() / Set.of(), Path.of(), SequencedCollection / SequencedSet, text blocks.
  • [/] Regexes use a precompiled Pattern.compile(...) constant, not String.matches(...).
  • [/] Background work uses org.jabref.logic.util.BackgroundTask, not new Thread().
  • No commented-out code, no trivial comments restating the code, no AI-disclosure comments in source.
  • Markdown Javadoc (///) uses Markdown syntax, not JavaDoc inline tags: `code` instead of {@code}, [ClassName] instead of {@link}.

User-facing text

  • All user-facing text localized (Localization.lang in Java, % prefix in FXML).
  • Sentence case (not Title Case); no trailing !; labels do not end with :.
  • [/] Variance expressed with placeholders ("...: %0"), not string concatenation.

Security

  • [/] User-controlled data (request params, entry fields, file contents) is HTML-escaped before being written into any text/html response — including exception/error messages, not just the success body (XSS).

Tests

  • Behavior changes in org.jabref.model / org.jabref.logic have added or updated tests.
  • Tests assert object contents (assertEquals), use plain JUnit asserts (not AssertJ), have no @DisplayName, do not catch exceptions (let them propagate so JUnit reports setup/teardown failures directly), and use @TempDir instead of manual temp directories.
  • [/] Fetcher tests hit the live endpoints — the remote API is not mocked or stubbed (automated-review suggestions to mock it are rejected on purpose).

2. Verification commands

  • ./gradlew :jablib:check (or ./gradlew check for all modules).
  • ./gradlew checkstyleMain checkstyleTest checkstyleJmh.
  • ./gradlew modernizer.
  • ./gradlew --no-configuration-cache :rewriteDryRun reports no changes (run ./gradlew rewriteRun to fix).
  • ./gradlew javadoc.
  • npx markdownlint-cli2 "docs/**/*.md" "*.md" (only if Markdown changed).
  • [/] Only if formatting is still off after rewriteRun: docker run -v $(pwd):/github/workspace ghcr.io/leventebajczi/intellij-format:master "*.java" "" ".idea/codeStyles/Project.xml".

3. Documentation

  • CHANGELOG.md entry added if the change is visible to the user (end-user wording, no extra blank lines, sorted in next to existing entries about the same component/feature). Link the issue if one exists; link the PR only when no issue exists. Use TODO as the placeholder when neither is known yet — never a fake number. No entry for fixes to changes that were themselves introduced after the last release (feature only in ## [Unreleased]) — update the existing unreleased entry instead if needed.
  • Searched jabref/issues and jabref-koppor/issues for a related issue; linked only on a confident match, otherwise kept TODO (no closes/fixes for merely-similar issues).
  • Requirement added to docs/requirements/<area>.md if the change is a new feature or significant bug fix (skip for refactors, minor fixes, and internal changes).
  • [/] Developer documentation under docs/ updated if behavior or architecture changed.

4. Pull request

  • PR body built from .github/PULL_REQUEST_TEMPLATE.md, every section filled.
  • All checklist items kept and marked [x], [ ], or [/].
  • All HTML comments removed from the PR body.
  • PR created with gh pr create --body-file <file> (not --body).
  • [/] If CHANGELOG.md used a TODO placeholder (no issue confidently identified yet — an existing issue link always stays), it was replaced with the real PR-number link after PR creation, then committed and pushed. If an issue is identified or created later, the link is switched to the issue.

Checklist

  • I own the copyright of the code submitted and I license it under the MIT license
  • If AI tools were used, I disclosed them in the "AI usage" section and reviewed, understood, and take full ownership of all AI-generated code
  • I manually tested my changes in running JabRef (always required)
  • I added JUnit tests for changes (if applicable)
  • I added screenshots in the PR description (if change is visible to the user)
  • I added one sentence (max 20 words) to CHANGELOG.md describing the change from the user's point of view (if the change is visible to the user)
  • I checked the user documentation for up to dateness and submitted a pull request to our user documentation repository

🤖 Generated with Claude Code

The separator is stored in the library's metadata and editable in the General tab of the library properties. Libraries without a declared separator keep the one their keyword fields already use, so opening a library no longer rewrites every keyword field to the global preference. Fixes JabRef/jabref-issue-melting-pot#1353.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018zp2dm93rwWgk6KAy2nm1D
@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Add per-library keyword separator handling

🐞 Bug fix ✨ Enhancement 🧪 Tests 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Stores and exposes keyword separators independently for each library.
• Preserves existing keyword formatting by inferring separators when metadata is absent.
• Applies library separators consistently across editing, importing, merging, grouping, and
 searching.
Diagram

graph TD
  A["BibTeX parser"] --> B["Delimiter inference"] --> C["Library metadata"] --> D["Context resolution"] --> E["Keyword workflows"]
  F["Properties UI"] --> C
  C --> G["Metadata serializer"] --> H["BibTeX library"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Preserve fields without inferring a library separator
  • ➕ Avoids heuristic delimiter selection and implicit metadata creation.
  • ➕ Guarantees opening a library never changes separator metadata.
  • ➖ Keyword-aware features would still require an unresolved separator.
  • ➖ Editing or merging could use the global preference and produce mixed delimiters.
2. Infer separators independently per keyword field
  • ➕ Preserves heterogeneous libraries without selecting one dominant delimiter.
  • ➕ Avoids adding inferred library metadata.
  • ➖ Editors, groups, search, and citation patterns still require one library-wide separator.
  • ➖ New or merged values could remain inconsistent across entries.

Recommendation: The PR's library-wide metadata setting with inference is the best compromise: it preserves consistently formatted legacy libraries while giving every keyword-dependent workflow one deterministic separator. Explicit metadata remains authoritative, and ambiguous or delimiter-free libraries retain the global fallback.

Files changed (38) +248 / -92

Enhancement (9) +75 / -9
FieldEditors.javaProvide database context to tag editors +2/-2

Provide database context to tag editors

• Passes the current database context when constructing keyword and groups editors so they can use library-specific separators.

jabgui/src/main/java/org/jabref/gui/fieldeditors/FieldEditors.java

GeneralPropertiesView.javaBind the keyword separator property field +2/-0

Bind the keyword separator property field

• Adds the General-tab text field binding for viewing and editing the library keyword separator.

jabgui/src/main/java/org/jabref/gui/libraryproperties/general/GeneralPropertiesView.java

GeneralPropertiesViewModel.javaLoad and store the library keyword separator +13/-0

Load and store the library keyword separator

• Displays the effective separator and persists its first character in library metadata. Empty input clears the metadata override.

jabgui/src/main/java/org/jabref/gui/libraryproperties/general/GeneralPropertiesViewModel.java

GeneralProperties.fxmlAdd keyword separator to General properties +5/-0

Add keyword separator to General properties

• Adds a localized label and compact text field for configuring the library keyword separator.

jabgui/src/main/resources/org/jabref/gui/libraryproperties/general/GeneralProperties.fxml

MetaDataSerializer.javaSerialize the library keyword separator +2/-0

Serialize the library keyword separator

• Includes the optional keyword separator in JabRef metadata written to library files.

jablib/src/main/java/org/jabref/logic/exporter/MetaDataSerializer.java

BibtexParser.javaInfer missing keyword separator metadata +10/-4

Infer missing keyword separator metadata

• Guesses a separator from parsed keyword fields before metadata processing and stores it when the library has no explicit declaration. Declared metadata remains authoritative.

jablib/src/main/java/org/jabref/logic/importer/fileformat/BibtexParser.java

MetaDataParser.javaParse keyword separator metadata +9/-1

Parse keyword separator metadata

• Reads valid single-character separator metadata and ignores invalid values. Group metadata parsing now uses the declared library separator when available.

jablib/src/main/java/org/jabref/logic/importer/util/MetaDataParser.java

BibDatabaseContext.javaCentralize effective separator resolution +6/-0

Centralize effective separator resolution

• Adds a helper that returns the library metadata separator or falls back to the global entry preference.

jablib/src/main/java/org/jabref/model/database/BibDatabaseContext.java

MetaData.javaModel per-library keyword separator metadata +26/-2

Model per-library keyword separator metadata

• Adds optional keyword separator state with mutation notifications, clearing support, equality, hashing, and diagnostic rendering.

jablib/src/main/java/org/jabref/model/metadata/MetaData.java

Bug fix (13) +76 / -24
ManageKeywordsDialog.javaResolve the active library separator for keyword management +6/-1

Resolve the active library separator for keyword management

• Injects the state manager and passes the active database's resolved separator into the keyword-management view model, falling back globally when no database is active.

jabgui/src/main/java/org/jabref/gui/edit/ManageKeywordsDialog.java

GroupsEditor.javaUse the library separator in the groups editor +4/-2

Use the library separator in the groups editor

• Accepts the database context and resolves the separator from library metadata before constructing the groups view model.

jabgui/src/main/java/org/jabref/gui/fieldeditors/GroupsEditor.java

KeywordsEditor.javaUse the library separator in the keywords editor +4/-2

Use the library separator in the keywords editor

• Accepts the database context and supplies its resolved keyword separator to the editor view model.

jabgui/src/main/java/org/jabref/gui/fieldeditors/KeywordsEditor.java

JabRefFrameViewModel.javaUse library separators for imported group assignments +1/-1

Use library separators for imported group assignments

• Assigns directly imported entries to groups using the target library's effective keyword separator.

jabgui/src/main/java/org/jabref/gui/frame/JabRefFrameViewModel.java

GroupDialogViewModel.javaApply the library separator throughout group creation +4/-4

Apply the library separator throughout group creation

• Uses the current database separator for delimiter validation, explicit groups, and keyword-search groups.

jabgui/src/main/java/org/jabref/gui/groups/GroupDialogViewModel.java

ImportEntriesViewModel.javaMerge imports with the target library separator +3/-3

Merge imports with the target library separator

• Uses the destination library separator for database merging, metadata merging, and post-import group assignment.

jabgui/src/main/java/org/jabref/gui/importer/ImportEntriesViewModel.java

AddGroupImportEntriesAction.javaHonor metadata when creating import groups +1/-1

Honor metadata when creating import groups

• Resolves the group separator from library metadata before falling back to the global keyword preference.

jabgui/src/main/java/org/jabref/gui/importer/actions/AddGroupImportEntriesAction.java

ThreeWayMergeView.javaResolve library separator for three-way merges +5/-2

Resolve library separator for three-way merges

• Obtains the active library separator and supplies it consistently to field mergers and keyword rendering.

jabgui/src/main/java/org/jabref/gui/mergeentries/threewaymerge/ThreeWayMergeView.java

CitationKeyGenerator.javaUse library separators in citation-key patterns +12/-2

Use library separators in citation-key patterns

• Captures the separator declared in database metadata for context-based generators while retaining the preference fallback for other constructors.

jablib/src/main/java/org/jabref/logic/citationkeypattern/CitationKeyGenerator.java

KeywordImportNormalizer.javaInfer and preserve library keyword separators +31/-2

Infer and preserve library keyword separators

• Adds separator inference based on accepted delimiter frequency and overloads normalization to accept a library separator. Existing fields are left unchanged when they already parse correctly with that separator.

jablib/src/main/java/org/jabref/logic/importer/KeywordImportNormalizer.java

BibtexImporter.javaNormalize imports with the resolved library separator +3/-2

Normalize imports with the resolved library separator

• Obtains the effective separator from the parsed database context before normalizing keyword fields.

jablib/src/main/java/org/jabref/logic/importer/fileformat/BibtexImporter.java

InMemoryLibrarySearcher.javaSearch keywords with the library separator +1/-1

Search keywords with the library separator

• Initializes in-memory search using the effective separator from the database context.

jablib/src/main/java/org/jabref/logic/search/inmemory/InMemoryLibrarySearcher.java

BibFieldsIndexer.javaIndex keywords with the library separator +1/-1

Index keywords with the library separator

• Uses the database context's effective separator when indexing keyword-bearing fields.

jablib/src/main/java/org/jabref/logic/search/sqlbased/indexing/BibFieldsIndexer.java

Refactor (6) +18 / -28
ManageKeywordsViewModel.javaAccept an explicit keyword separator +3/-6

Accept an explicit keyword separator

• Replaces the global preference dependency with a resolved separator supplied by the dialog for parsing and saving keyword changes.

jabgui/src/main/java/org/jabref/gui/edit/ManageKeywordsViewModel.java

GroupsEditorViewModel.javaReceive the resolved group separator directly +2/-3

Receive the resolved group separator directly

• Removes the preferences dependency and stores the separator selected by the enclosing library context.

jabgui/src/main/java/org/jabref/gui/fieldeditors/GroupsEditorViewModel.java

KeywordsEditorViewModel.javaReceive the resolved keyword separator directly +2/-3

Receive the resolved keyword separator directly

• Decouples keyword parsing from global preferences by accepting the effective separator as a constructor argument.

jabgui/src/main/java/org/jabref/gui/fieldeditors/KeywordsEditorViewModel.java

FieldMergerFactory.javaConstruct field mergers with an explicit separator +5/-6

Construct field mergers with an explicit separator

• Replaces the preference object with a resolved separator and forwards it to keyword and group mergers.

jabgui/src/main/java/org/jabref/gui/mergeentries/threewaymerge/fieldsmerger/FieldMergerFactory.java

GroupMerger.javaMerge groups with the supplied delimiter +3/-5

Merge groups with the supplied delimiter

• Removes global preference lookup and uses the delimiter resolved by the merge workflow.

jabgui/src/main/java/org/jabref/gui/mergeentries/threewaymerge/fieldsmerger/GroupMerger.java

KeywordMerger.javaMerge keywords with the supplied delimiter +3/-5

Merge keywords with the supplied delimiter

• Uses an explicit library-aware delimiter instead of obtaining one from global preferences.

jabgui/src/main/java/org/jabref/gui/mergeentries/threewaymerge/fieldsmerger/KeywordMerger.java

Tests (8) +75 / -30
ManageKeywordsViewModelTest.javaAdapt keyword-management tests to explicit separators +1/-5

Adapt keyword-management tests to explicit separators

• Constructs the view model with a separator directly and removes the unnecessary preferences mock.

jabgui/src/test/java/org/jabref/gui/edit/ManageKeywordsViewModelTest.java

KeywordsEditorViewModelTest.javaAdapt keyword editor tests to explicit separators +1/-4

Adapt keyword editor tests to explicit separators

• Supplies a comma separator directly to the view model instead of mocking entry preferences.

jabgui/src/test/java/org/jabref/gui/fieldeditors/KeywordsEditorViewModelTest.java

FieldRowViewModelTest.javaAdapt field-row merge tests to the new factory API +1/-8

Adapt field-row merge tests to the new factory API

• Constructs the field merger factory with an explicit comma separator and removes preference mocking.

jabgui/src/test/java/org/jabref/gui/mergeentries/FieldRowViewModelTest.java

GroupMergerTest.javaAdapt group merger tests to explicit delimiters +1/-3

Adapt group merger tests to explicit delimiters

• Instantiates the group merger directly with each parameterized delimiter.

jabgui/src/test/java/org/jabref/gui/mergeentries/GroupMergerTest.java

MetaDataSerializerTest.javaTest keyword separator serialization +7/-0

Test keyword separator serialization

• Verifies that a semicolon separator is emitted under the new metadata key using the expected encoded representation.

jablib/src/test/java/org/jabref/logic/exporter/MetaDataSerializerTest.java

KeywordImportNormalizerTest.javaTest separator inference and formatting preservation +27/-0

Test separator inference and formatting preservation

• Covers preserving already compatible fields, selecting the most frequent delimiter, and returning no guess when delimiters are absent.

jablib/src/test/java/org/jabref/logic/importer/KeywordImportNormalizerTest.java

BibtexImporterTest.javaTest library-aware BibTeX keyword imports +29/-10

Test library-aware BibTeX keyword imports

• Verifies inferred separators preserve existing fields, declared metadata controls normalization, and configured delimiter edge cases use the resolved library separator.

jablib/src/test/java/org/jabref/logic/importer/fileformat/BibtexImporterTest.java

MetaDataParserTest.javaTest keyword separator metadata parsing +8/-0

Test keyword separator metadata parsing

• Verifies that encoded separator metadata is parsed into the library metadata model.

jablib/src/test/java/org/jabref/logic/importer/util/MetaDataParserTest.java

Documentation (2) +4 / -1
CHANGELOG.mdDocument per-library keyword separators +1/-0

Document per-library keyword separators

• Adds an unreleased user-facing entry describing the library property and prevention of unwanted keyword rewrites.

CHANGELOG.md

import.mdDefine library-aware keyword normalization requirements +3/-1

Define library-aware keyword normalization requirements

• Updates import requirements to prioritize declared metadata, infer existing delimiters, and preserve fields already using the resolved separator.

docs/requirements/import.md

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. guessSeparator counts escaped delimiters ✓ Resolved 📘 Rule violation ≡ Correctness
Description
guessSeparator counts every configured candidate character, including escaped delimiters and
delimiters inside braces that KeywordList treats as literal keyword content. It can therefore
infer the wrong library separator and rewrite existing keyword fields with that separator, violating
the compatibility and preservation requirements.
Code

jablib/src/main/java/org/jabref/logic/importer/KeywordImportNormalizer.java[R47-50]

+            entry.getField(StandardField.KEYWORDS).ifPresent(keywords ->
+                    keywords.chars().mapToObj(symbol -> (char) symbol)
+                            .filter(candidates::contains)
+                            .forEach(symbol -> counts.merge(symbol, 1L, Long::sum)));
Evidence
Rule 4 requires compatibility to be preserved, but the new inference loop scans and counts raw
characters without tracking escaping or brace depth, whereas KeywordList recognizes delimiters
only when they are unescaped and at the top level. For example, foo\,bar\,baz;qux is
semicolon-separated but is inferred as comma-separated; because that inferred result is then
supplied as the library separator during BibTeX parsing and normalization, the field can be
rewritten contrary to the documented preservation behavior.

AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, and Focused Scope: AGENTS.md: Preserve Existing Architecture, Compatibility, ...

Comment thread jablib/src/main/java/org/jabref/logic/importer/KeywordImportNormalizer.java Outdated
Comment thread CHANGELOG.md Outdated
@jabref-machine jabref-machine added the status: changes-required Pull requests that are not yet complete label Sep 3, 2026
koppor and others added 6 commits September 3, 2026 09:48
GroupsEditor now receives BibEntryPreferences via its constructor
instead of pulling CliPreferences from the Injector (constructor-based
injection per ADR). Also fixes checkstyle findings in the branch.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017NmDLSsG1427ps5rztJXHT
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018zp2dm93rwWgk6KAy2nm1D
…nto keyword-separator-per-library

# Conflicts:
#	jabgui/src/main/java/org/jabref/gui/fieldeditors/GroupsEditor.java
…arator input

- guessSeparator now counts only top-level, unescaped delimiters outside
  braces, using the same scan as KeywordList parsing
- Library properties keyword separator field is limited to one character
- Shorten changelog entry

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017NmDLSsG1427ps5rztJXHT
@jabref-machine jabref-machine added status: ready-for-review Pull Requests that are ready to be reviewed by the maintainers and removed status: changes-required Pull requests that are not yet complete labels Sep 3, 2026
koppor and others added 3 commits September 3, 2026 10:36
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018zp2dm93rwWgk6KAy2nm1D
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018zp2dm93rwWgk6KAy2nm1D
The rewrite of keyword fields to the library's separator is now a field formatter, part of the default save actions and the cleanup dialog, and bound to the library's keyword separator on save and cleanup. Load applies the same formatter for in-memory consistency; ADR 0071 records the trade-off.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018zp2dm93rwWgk6KAy2nm1D
int startLine = line;
int startColumn = column;
try {
// A library without a declared separator keeps the one its keyword fields already use, so opening it does not rewrite them

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 bug: BibDesk static-group migration has already created/appended groups with the global separator (and a hard-coded comma) before this effective separator is known. Defer that migration until after metadata parsing and use the resulting separator.

librarySpecificDirectoryProperty.setValue(metaData.getLibrarySpecificFileDirectory().orElse("").trim());
userSpecificFileDirectoryProperty.setValue(metaData.getUserFileDirectory(preferences.getFilePreferences().getUserAndHost()).orElse("").trim());
laTexFileDirectoryProperty.setValue(metaData.getLatexFileDirectory(preferences.getFilePreferences().getUserAndHost()).map(Path::toString).orElse(""));
keywordSeparatorProperty.setValue(databaseContext.getKeywordSeparator(preferences.getBibEntryPreferences().getKeywordSeparator()).toString());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 risk: This displays the effective global fallback even when metadata has no override; storeSettings then writes it as an explicit library setting. Opening Library Properties and saving an unrelated option therefore freezes future global changes. Bind the field to metaData.getKeywordSeparator() (blank when absent).

Character separator = Optional.ofNullable(keywordSeparator)
.or(() -> Optional.ofNullable(preferences.getKeywordSeparator()))
.orElse(BibEntryPreferences.getDefault().getKeywordSeparator());
List<Character> delimiters = KeywordImportNormalizer.parseConfiguredDelimiters(preferences.getImportKeywordDelimiters());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 bug: If the accepted import delimiters exclude the library separator, this parses an already-valid field with the wrong delimiter. For example, import delimiter , plus library separator ; turns a;b into a\\;b. Include the separator in delimiters (or short-circuit a valid field) and add a regression test.

@Siedlerchr Siedlerchr left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional findings in unchanged files (GitHub cannot anchor inline comments outside the PR diff):

  • jabgui/src/main/java/org/jabref/gui/mergeentries/BatchEntryMergeWithFetchedDataAction.java:L64: 🔴 bug: batch fetched-data merges still pass the global separator. A semicolon library’s groups field can become mixed (one; two, three). Pass the active database’s effective separator.
  • jabgui/src/main/java/org/jabref/gui/pseudonymize/PseudonymizeAction.java:L51: 🟡 risk: pseudonymization still parses and writes group memberships using the global separator. Use the source library’s effective separator and preserve it in the generated context metadata.

}

@Override
public String format(@NonNull String value) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 risk: This formatter runs only on import, cleanup, or save actions; changing the separator in Library Properties merely updates metadata, so existing keyword fields are never migrated. Existing keyword-backed groups also retain their captured separator. Trigger an explicit, undoable migration when the setting changes, covering both keywords and groups.

@Siedlerchr

Copy link
Copy Markdown
Member

will fix it

Defer static-group migration until metadata determines the effective separator.
Keep fields and group definitions consistent in one undo operation.
Use the effective separator and retain explicit overrides in pseudonymized libraries.
@Siedlerchr

Copy link
Copy Markdown
Member

Addressed all outstanding feedback: BibDesk now uses the effective separator; library settings retain absent overrides and migrate fields/groups undoably; formatter, merge, and pseudonymization honor the library separator. Focused regression tests pass.

@Siedlerchr
Siedlerchr enabled auto-merge September 4, 2026 21:28
@Siedlerchr
Siedlerchr added this pull request to the merge queue Sep 4, 2026
@github-actions github-actions Bot added the status: to-be-merged PRs which are accepted and should go into the merge-queue. label Sep 4, 2026
Merged via the queue into main with commit 58a1d4d Sep 4, 2026
75 checks passed
@Siedlerchr
Siedlerchr deleted the keyword-separator-per-library branch September 4, 2026 21:41
koppor pushed a commit to JabRef/jabref-koppor that referenced this pull request Sep 5, 2026
origin/keyword-separator-per-library (JabRef#16835) and
origin/show-diff-button (JabRef#16832) no longer exist on either
remote; last night's run warned about both. Upstream has landed the
keyword-separator work itself, so experimental picks it up via
origin/main.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NPHwSBqteEYM7E2QgWhk8U
Siedlerchr added a commit to sanjaykumarmtt/jabref that referenced this pull request Sep 5, 2026
…16728

* upstream/main:
  Document improve AI Usage Policy (JabRef#16852)
  Fix openfasttrace buildtime concurrency issues (JabRef#16854)
  Render the JabCon gource video every 15 minutes
  Add "Show diff" to the save-before-closing dialog (JabRef#16832)
  Exclude Kotlin scripts from IDEA formatting (JabRef#16790)
  Support modifier keys entry drag drop (JabRef#16286)
  Chore(deps): Bump jablib/src/main/resources/csl-styles from `0819c0e` to `db768d4` (JabRef#16820)
  Add per-library keyword separator (JabRef#16835)
  Improve logging to find out which linked file has a flaw (JabRef#15680) (JabRef#16702)
  Fix accented arXiv title searches (JabRef#16825)
  Show progress indicator during identifier lookup in New Entry dialog (JabRef#16795)
  Open online file links via URL-aware browser call (JabRef#16774)
  Chore(deps): Bump org.controlsfx:controlsfx in /versions (JabRef#16847)
  Keep daytime continuous in the JabCon gource video
Siedlerchr added a commit to Siedlerchr/jabref that referenced this pull request Sep 5, 2026
* main:
  Fix `missing$` case warnings in BST VM (JabRef#16851)
  Start the JabCon gource video at the JabCon start time
  Add highlight words mode to Git Diff view (JabRef#16742)
  Document improve AI Usage Policy (JabRef#16852)
  Fix openfasttrace buildtime concurrency issues (JabRef#16854)
  Render the JabCon gource video every 15 minutes
  Add "Show diff" to the save-before-closing dialog (JabRef#16832)
  Exclude Kotlin scripts from IDEA formatting (JabRef#16790)
  Support modifier keys entry drag drop (JabRef#16286)
  Chore(deps): Bump jablib/src/main/resources/csl-styles from `0819c0e` to `db768d4` (JabRef#16820)
  Add per-library keyword separator (JabRef#16835)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants