From 391218349784843a8aab3558121db5036ac62c4c Mon Sep 17 00:00:00 2001 From: Dmitrij Zykovic Date: Wed, 7 Oct 2026 16:18:41 +0300 Subject: [PATCH 1/2] Made status --check decide .gitignore presence with the writer's CR-blind test --- cli/internal/check.sh | 7 ++++-- cli/lib/gitignore.sh | 32 ++++++++++++++++----------- cli/tests/e2e-negative.sh | 43 +++++++++++++++++++++++++++++++++++++ cli/tests/unit-gitignore.sh | 24 ++++++++++++++++++--- intelligence/rules/shell.md | 11 ++++++---- 5 files changed, 96 insertions(+), 21 deletions(-) diff --git a/cli/internal/check.sh b/cli/internal/check.sh index 4976c9f..bbeb686 100644 --- a/cli/internal/check.sh +++ b/cli/internal/check.sh @@ -150,14 +150,17 @@ while IFS= read -r target; do && [ "$(is_target_enabled "$manifest" "$value")" != "1" ]; then warn "enabled adapter '$target' requires enabled adapter '$value'" fi + # Presence is the writer's own test: a line `init` treats as present + # and leaves alone must not be reported missing here, or the warning + # can never clear — a CRLF .gitignore on Linux and macOS did exactly that. if [ "$(is_target_enabled "$manifest" "$target")" = "1" ]; then case "$kind" in ignore) - grep -Fqx -- "$value" "$IP_ROOT/.gitignore" 2>/dev/null \ + ignore_file_has_line "$IP_ROOT/.gitignore" "$value" \ || warn "adapter '$target' Git policy is missing '$value'" ;; include) - if ! grep -Fqx -- "!$value" "$IP_ROOT/.gitignore" 2>/dev/null; then + if ! ignore_file_has_line "$IP_ROOT/.gitignore" "!$value"; then warn "adapter '$target' Git policy is missing '!$value'" elif git -C "$IP_ROOT" rev-parse --is-inside-work-tree >/dev/null 2>&1; then if git -C "$IP_ROOT" check-ignore -q --no-index -- "$value"; then diff --git a/cli/lib/gitignore.sh b/cli/lib/gitignore.sh index 3f4bd5e..592d018 100644 --- a/cli/lib/gitignore.sh +++ b/cli/lib/gitignore.sh @@ -13,12 +13,13 @@ IS_CR=$'\r' IS_LF=$'\n' IS_CRLF=$'\r\n' -# An ignore file checked out on Windows can hold CRLF, and a CR belongs to the -# pattern Git matches — so these two helpers decide presence ignoring it, and -# append in whatever ending the file already uses. Comparing with the CR -# attached made every existing line look absent on Linux and macOS (where it is -# part of the line, unlike under MSYS), so each alignment appended an LF copy of -# a line that was already there and the file grew forever. +# An ignore file checked out on Windows can hold CRLF. Git drops one trailing +# CR from each line before matching, so `foo` and `foo` are the same rule: +# these helpers decide presence ignoring that CR, and append in whatever ending +# the file already uses. Comparing with the CR attached made every existing +# line look absent on Linux and macOS (where it is part of the line, unlike +# under MSYS), so each alignment appended an LF copy of a line that was already +# there and the file grew forever. # ignore_file_eol_var — set IS_IGNORE_EOL from the file's first line. ignore_file_eol_var() { @@ -32,12 +33,19 @@ ignore_file_eol_var() { } # ignore_file_has_line — true when the file lists exactly this -# line, with or without a trailing CR. +# line, with or without a trailing CR. The one presence test for an ignore +# file: the writer and `status --check` both ask it, so a line one appends is a +# line the other reports present. Decided in bash, because an exact-line grep +# answers per platform — MSYS grep never sees the CR, Linux and macOS grep keep +# it as part of the line. ignore_file_has_line() { - local file="$1" line="$2" + local file="$1" line="$2" entry="" [ -f "$file" ] || return 1 - grep -Fqx -- "$line" "$file" 2>/dev/null && return 0 - grep -Fqx -- "$line$IS_CR" "$file" 2>/dev/null + while IFS= read -r entry || [ -n "$entry" ]; do + [ "${entry%"$IS_CR"}" = "$line" ] && return 0 + entry="" + done < "$file" + return 1 } # ignore_file_append_line — append in the file's own ending. @@ -93,8 +101,8 @@ gitignore_collapse_duplicates() { # Read and write the file's own bytes, without awk: on Windows it reads in # text mode and would hand back every line stripped of its CR, rewriting a - # CRLF file as LF. A line's CR is significant to Git, and either way the - # lines this function does not remove must survive byte-for-byte. + # CRLF file as LF. The lines this function does not remove must survive + # byte-for-byte, whatever their ending. line="" while IFS= read -r line; do lines[${#lines[@]}]="$line" diff --git a/cli/tests/e2e-negative.sh b/cli/tests/e2e-negative.sh index e59d71b..c854171 100644 --- a/cli/tests/e2e-negative.sh +++ b/cli/tests/e2e-negative.sh @@ -909,6 +909,49 @@ xok "" "$PROJ" init --no-sync chk cmp -s "$OUT/gitignore-collapsed" "$PROJ/.gitignore" xok "all good" "$PROJ" status --check +# A Windows checkout can hold the .gitignore as CRLF. Git drops each line's +# trailing CR and so does the writer's presence test, but `status --check` +# compared whole lines with grep: on Linux and macOS it reported every present +# pattern missing while `init` found nothing to add, so the warning never +# cleared. The fixture is written and inspected in bash — under MSYS grep never +# sees a CR, and a grep-based assertion here would pass measuring nothing. +CR=$'\r' +# gi_crlf_shape — "crlf " when every line of the project .gitignore ends in +# CR, "mixed " otherwise; counts the lines that are CLAUDE.md. +gi_crlf_shape() { + local l="" shape=crlf n=0 + while IFS= read -r l || [ -n "$l" ]; do + case "$l" in *"$CR") ;; *) shape=mixed ;; esac + if [ "${l%"$CR"}" = 'CLAUDE.md' ]; then n=$((n + 1)); fi + l="" + done < "$PROJ/.gitignore" + printf '%s %s' "$shape" "$n" +} +cp "$PROJ/.gitignore" "$OUT/gitignore-lf" +gi_line="" +while IFS= read -r gi_line || [ -n "$gi_line" ]; do + # One managed pattern left out, so the check has a real absence to report. + [ "$gi_line" = 'CLAUDE.md' ] || printf '%s\r\n' "$gi_line" + gi_line="" +done < "$OUT/gitignore-lf" > "$PROJ/.gitignore" +[ "$(gi_crlf_shape)" = "crlf 0" ] \ + || { echo "FAIL: the CRLF .gitignore fixture is '$(gi_crlf_shape)', want 'crlf 0'"; fail=1; } +xfail "Git policy is missing 'CLAUDE.md'" "$PROJ" status --check +gi_missing="$(printf '%s\n' "$OUTPUT" | grep -cF 'Git policy is missing' || true)" +if [ "$gi_missing" != 1 ]; then + echo "FAIL: status --check reports $gi_missing patterns missing from a CRLF .gitignore, want only 'CLAUDE.md'" + printf '%s\n' "$OUTPUT" | grep -F 'Git policy is missing' | head -6 || true + fail=1 +fi +xok "" "$PROJ" init --no-sync +[ "$(gi_crlf_shape)" = "crlf 1" ] \ + || { echo "FAIL: init left the CRLF .gitignore '$(gi_crlf_shape)', want 'crlf 1'"; fail=1; } +xok "all good" "$PROJ" status --check +cp "$PROJ/.gitignore" "$OUT/gitignore-crlf" +xok "" "$PROJ" init --no-sync +chk cmp -s "$OUT/gitignore-crlf" "$PROJ/.gitignore" +cp "$OUT/gitignore-lf" "$PROJ/.gitignore" + # AGENTS.md-dependent targets cannot be enabled into a manifest the engine # would reject, and agents cannot be disabled while one remains enabled. xok "disabled: claude" "$PROJ" adapter disable claude diff --git a/cli/tests/unit-gitignore.sh b/cli/tests/unit-gitignore.sh index a626dca..3c46eb3 100644 --- a/cli/tests/unit-gitignore.sh +++ b/cli/tests/unit-gitignore.sh @@ -131,9 +131,9 @@ ignore_file_eol_var "$D/.gitignore" # Compared through a variable: `$'\r\n'` written inside a command substitution # is not expanded by bash, so the check would silently always fail. [ "$IS_IGNORE_EOL" = "$CRLF" ] || { echo "FAIL: CRLF ending not detected"; fail=1; } -# A CR belongs to the pattern Git matches, so presence must ignore it while the -# append keeps it: comparing with the CR attached made every existing line look -# absent on Linux and macOS, and alignment appended an LF copy every run. +# Git drops a line's trailing CR, so presence must ignore it while the append +# keeps it: comparing with the CR attached made every existing line look absent +# on Linux and macOS, and alignment appended an LF copy every run. chk ignore_file_has_line "$D/.gitignore" '!.claude/' chk ignore_file_has_line "$D/.gitignore" "$HEADER" gitignore_add_line "$D" '!.claude/' @@ -142,6 +142,24 @@ gitignore_add_line "$D" '.codex/*' is "new line appended as CRLF" "5" "$(crlf_lines "$D/.gitignore")" is "no LF-only line introduced" "5" "$(total_lines "$D/.gitignore")" +echo "== presence is one exact line, ignoring only its trailing CR ==" +D="$(fixture presence)" +printf '.claude/*\r\n!.claude/settings.json\r\nnested/dir/\r\r\nlast-line\r' > "$D/.gitignore" +chk ignore_file_has_line "$D/.gitignore" '.claude/*' +chk ignore_file_has_line "$D/.gitignore" '!.claude/settings.json' +# A final line without a newline is still a line, with or without its CR. +chk ignore_file_has_line "$D/.gitignore" 'last-line' +# Exact and literal: no prefix, substring or glob reading of either side. +chknot ignore_file_has_line "$D/.gitignore" '.claude/' +chknot ignore_file_has_line "$D/.gitignore" '!.claude/settings' +chknot ignore_file_has_line "$D/.gitignore" '.c*' +chknot ignore_file_has_line "$D/.gitignore" '.claude/x' +# Git drops exactly one CR, so a second one is part of that rule. +chknot ignore_file_has_line "$D/.gitignore" 'nested/dir/' +chknot ignore_file_has_line "$OUT/absent/.gitignore" '.claude/*' +printf 'last-line' > "$D/.gitignore" +chk ignore_file_has_line "$D/.gitignore" 'last-line' + echo "== repeated alignment leaves a CRLF file alone ==" D="$(fixture crlf-stable)" printf '%s\r\n.claude/*\r\n!.claude/\r\n!.claude/settings.json\r\n' "$HEADER" > "$D/.gitignore" diff --git a/intelligence/rules/shell.md b/intelligence/rules/shell.md index b49f725..b5c0687 100644 --- a/intelligence/rules/shell.md +++ b/intelligence/rules/shell.md @@ -27,16 +27,19 @@ see any of these. A reader that rewrites a file it does not own must round-trip the bytes it keeps. awk on Windows reads in text mode, so passing a CRLF file through it silently -rewrites the whole file as LF — for a `.gitignore`, where a `\r` is part of the -pattern Git matches, that is a content change. Read and write such a file with -`read`/`printf`. +rewrites the whole file as LF — for a tracked `.gitignore` that is a whole-file +diff the project never made, even though Git drops one trailing `\r` per line and +reads both alike. Read and write such a file with `read`/`printf`. Decide anything about a CR in Bash, not in a text-mode tool: under MSYS `grep` never sees one, while on Linux and macOS it is part of the line, so the same `grep -Fx` answers differently per platform — in tests that reads as a passing assertion measuring nothing. `read` sees the CR everywhere. Hold `\r` in a variable too: bash does not expand `$'\r'` inside a command substitution, so the -identical expression stops stripping it depending on the caller. +identical expression stops stripping it depending on the caller. Whether an +ignore file lists a line is `ignore_file_has_line` (`cli/lib/gitignore.sh`) for +the writer and `status --check` alike: a second test is how the check came to +report missing what the writer had already written. Strip `\r` in awk readers: manifests, rules and frontmatter reach the engine from CRLF checkouts. From 8034dc50dd218cf33347eab2906fa544275e9028 Mon Sep 17 00:00:00 2001 From: Dmitrij Zykovic Date: Wed, 7 Oct 2026 16:24:25 +0300 Subject: [PATCH 2/2] Selected 0.19.0 for the CRLF status check fix --- CHANGELOG.md | 6 ++++++ engine/VERSION | 2 +- examples/cli-project/intelligence.yaml | 4 ++-- examples/dotnet-api-with-react-frontend/intelligence.lock | 6 +++--- examples/dotnet-api-with-react-frontend/intelligence.yaml | 4 ++-- examples/go-api-with-antigravity/intelligence.lock | 6 +++--- examples/go-api-with-antigravity/intelligence.yaml | 4 ++-- examples/go-api-with-opencode/intelligence.lock | 6 +++--- examples/go-api-with-opencode/intelligence.yaml | 4 ++-- examples/go-api-with-pi-and-codex/intelligence.lock | 6 +++--- examples/go-api-with-pi-and-codex/intelligence.yaml | 4 ++-- examples/go-api/intelligence.lock | 6 +++--- examples/go-api/intelligence.yaml | 4 ++-- examples/platform-with-submodules/intelligence.lock | 6 +++--- examples/platform-with-submodules/intelligence.yaml | 4 ++-- examples/with-remote-skills/intelligence.yaml | 4 ++-- intelligence.lock | 6 +++--- intelligence.yaml | 4 ++-- 18 files changed, 46 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 069cd0a..1c2ed89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to Intelligence are recorded here. Legacy Intelligence Sync history remains in its [archive](https://github.com/ainova-systems/intelligence-sync/blob/main/CHANGELOG.md). +## [0.19.0] + +### Fixed + +- `status --check` no longer reports `.gitignore` patterns as missing when the file has CRLF line endings on Linux and macOS; it decides presence the way the `.gitignore` writer does, so `intelligence init` clears the finding (#45). + ## [0.18.1] ### Changed diff --git a/engine/VERSION b/engine/VERSION index 249afd5..1cf0537 100644 --- a/engine/VERSION +++ b/engine/VERSION @@ -1 +1 @@ -0.18.1 +0.19.0 diff --git a/examples/cli-project/intelligence.yaml b/examples/cli-project/intelligence.yaml index 376261b..32200b4 100644 --- a/examples/cli-project/intelligence.yaml +++ b/examples/cli-project/intelligence.yaml @@ -11,7 +11,7 @@ project: name: cli-project -schema_version: "0.18.1" +schema_version: "0.19.0" # Package sources come first, project sources last: adapters copy in order # and the last write wins, so a project file overrides a same-named package @@ -38,7 +38,7 @@ targets: # CLI-owned blocks — the engine never reads below this line. packages: "@ainova-systems/sync": - version: "0.18.1" + version: "0.19.0" "@ainova-systems/core": version: "^0.3.0" diff --git a/examples/dotnet-api-with-react-frontend/intelligence.lock b/examples/dotnet-api-with-react-frontend/intelligence.lock index 4576ae2..11834a3 100644 --- a/examples/dotnet-api-with-react-frontend/intelligence.lock +++ b/examples/dotnet-api-with-react-frontend/intelligence.lock @@ -1,10 +1,10 @@ # Generated by the intelligence CLI. Do not edit. lockfile_version: 1 -engine_version: "0.18.1" +engine_version: "0.19.0" packages: "@ainova-systems/sync": - requested: "0.18.1" + requested: "0.19.0" url: "https://github.com/ainova-systems/intelligence.git" path: "packages/sync" - resolved: "v0.18.1" + resolved: "v0.19.0" sha: "" diff --git a/examples/dotnet-api-with-react-frontend/intelligence.yaml b/examples/dotnet-api-with-react-frontend/intelligence.yaml index 80c3e4d..93baf24 100644 --- a/examples/dotnet-api-with-react-frontend/intelligence.yaml +++ b/examples/dotnet-api-with-react-frontend/intelligence.yaml @@ -6,7 +6,7 @@ project: name: my-platform -schema_version: "0.18.1" +schema_version: "0.19.0" sources: rules: @@ -50,4 +50,4 @@ ignore: # from the CLI bundle. packages: "@ainova-systems/sync": - version: "0.18.1" + version: "0.19.0" diff --git a/examples/go-api-with-antigravity/intelligence.lock b/examples/go-api-with-antigravity/intelligence.lock index 4576ae2..11834a3 100644 --- a/examples/go-api-with-antigravity/intelligence.lock +++ b/examples/go-api-with-antigravity/intelligence.lock @@ -1,10 +1,10 @@ # Generated by the intelligence CLI. Do not edit. lockfile_version: 1 -engine_version: "0.18.1" +engine_version: "0.19.0" packages: "@ainova-systems/sync": - requested: "0.18.1" + requested: "0.19.0" url: "https://github.com/ainova-systems/intelligence.git" path: "packages/sync" - resolved: "v0.18.1" + resolved: "v0.19.0" sha: "" diff --git a/examples/go-api-with-antigravity/intelligence.yaml b/examples/go-api-with-antigravity/intelligence.yaml index 52b6bac..f7d6931 100644 --- a/examples/go-api-with-antigravity/intelligence.yaml +++ b/examples/go-api-with-antigravity/intelligence.yaml @@ -6,7 +6,7 @@ project: name: my-api -schema_version: "0.18.1" +schema_version: "0.19.0" sources: rules: @@ -36,4 +36,4 @@ targets: # from the CLI bundle. packages: "@ainova-systems/sync": - version: "0.18.1" + version: "0.19.0" diff --git a/examples/go-api-with-opencode/intelligence.lock b/examples/go-api-with-opencode/intelligence.lock index 4576ae2..11834a3 100644 --- a/examples/go-api-with-opencode/intelligence.lock +++ b/examples/go-api-with-opencode/intelligence.lock @@ -1,10 +1,10 @@ # Generated by the intelligence CLI. Do not edit. lockfile_version: 1 -engine_version: "0.18.1" +engine_version: "0.19.0" packages: "@ainova-systems/sync": - requested: "0.18.1" + requested: "0.19.0" url: "https://github.com/ainova-systems/intelligence.git" path: "packages/sync" - resolved: "v0.18.1" + resolved: "v0.19.0" sha: "" diff --git a/examples/go-api-with-opencode/intelligence.yaml b/examples/go-api-with-opencode/intelligence.yaml index 99a0add..2eac475 100644 --- a/examples/go-api-with-opencode/intelligence.yaml +++ b/examples/go-api-with-opencode/intelligence.yaml @@ -5,7 +5,7 @@ project: name: my-api -schema_version: "0.18.1" +schema_version: "0.19.0" sources: rules: @@ -35,4 +35,4 @@ targets: # from the CLI bundle. packages: "@ainova-systems/sync": - version: "0.18.1" + version: "0.19.0" diff --git a/examples/go-api-with-pi-and-codex/intelligence.lock b/examples/go-api-with-pi-and-codex/intelligence.lock index 4576ae2..11834a3 100644 --- a/examples/go-api-with-pi-and-codex/intelligence.lock +++ b/examples/go-api-with-pi-and-codex/intelligence.lock @@ -1,10 +1,10 @@ # Generated by the intelligence CLI. Do not edit. lockfile_version: 1 -engine_version: "0.18.1" +engine_version: "0.19.0" packages: "@ainova-systems/sync": - requested: "0.18.1" + requested: "0.19.0" url: "https://github.com/ainova-systems/intelligence.git" path: "packages/sync" - resolved: "v0.18.1" + resolved: "v0.19.0" sha: "" diff --git a/examples/go-api-with-pi-and-codex/intelligence.yaml b/examples/go-api-with-pi-and-codex/intelligence.yaml index 788b3d6..5e9bfe7 100644 --- a/examples/go-api-with-pi-and-codex/intelligence.yaml +++ b/examples/go-api-with-pi-and-codex/intelligence.yaml @@ -5,7 +5,7 @@ project: name: my-api -schema_version: "0.18.1" +schema_version: "0.19.0" sources: rules: @@ -36,4 +36,4 @@ targets: # from the CLI bundle. packages: "@ainova-systems/sync": - version: "0.18.1" + version: "0.19.0" diff --git a/examples/go-api/intelligence.lock b/examples/go-api/intelligence.lock index 4576ae2..11834a3 100644 --- a/examples/go-api/intelligence.lock +++ b/examples/go-api/intelligence.lock @@ -1,10 +1,10 @@ # Generated by the intelligence CLI. Do not edit. lockfile_version: 1 -engine_version: "0.18.1" +engine_version: "0.19.0" packages: "@ainova-systems/sync": - requested: "0.18.1" + requested: "0.19.0" url: "https://github.com/ainova-systems/intelligence.git" path: "packages/sync" - resolved: "v0.18.1" + resolved: "v0.19.0" sha: "" diff --git a/examples/go-api/intelligence.yaml b/examples/go-api/intelligence.yaml index f3d34dd..dedc7a3 100644 --- a/examples/go-api/intelligence.yaml +++ b/examples/go-api/intelligence.yaml @@ -4,7 +4,7 @@ project: name: my-api -schema_version: "0.18.1" +schema_version: "0.19.0" sources: rules: @@ -35,4 +35,4 @@ targets: # from the CLI bundle. packages: "@ainova-systems/sync": - version: "0.18.1" + version: "0.19.0" diff --git a/examples/platform-with-submodules/intelligence.lock b/examples/platform-with-submodules/intelligence.lock index 4576ae2..11834a3 100644 --- a/examples/platform-with-submodules/intelligence.lock +++ b/examples/platform-with-submodules/intelligence.lock @@ -1,10 +1,10 @@ # Generated by the intelligence CLI. Do not edit. lockfile_version: 1 -engine_version: "0.18.1" +engine_version: "0.19.0" packages: "@ainova-systems/sync": - requested: "0.18.1" + requested: "0.19.0" url: "https://github.com/ainova-systems/intelligence.git" path: "packages/sync" - resolved: "v0.18.1" + resolved: "v0.19.0" sha: "" diff --git a/examples/platform-with-submodules/intelligence.yaml b/examples/platform-with-submodules/intelligence.yaml index c2cbda7..bb2d4a1 100644 --- a/examples/platform-with-submodules/intelligence.yaml +++ b/examples/platform-with-submodules/intelligence.yaml @@ -6,7 +6,7 @@ project: name: my-platform -schema_version: "0.18.1" +schema_version: "0.19.0" sources: rules: @@ -53,4 +53,4 @@ submodules: # from the CLI bundle. packages: "@ainova-systems/sync": - version: "0.18.1" + version: "0.19.0" diff --git a/examples/with-remote-skills/intelligence.yaml b/examples/with-remote-skills/intelligence.yaml index e84f6dd..72466b5 100644 --- a/examples/with-remote-skills/intelligence.yaml +++ b/examples/with-remote-skills/intelligence.yaml @@ -8,7 +8,7 @@ project: name: my-app -schema_version: "0.18.1" +schema_version: "0.19.0" # Package sources come first, project sources last: adapters copy in order and # the last write wins, so a project file overrides a same-named package file. @@ -43,7 +43,7 @@ targets: # fresh clone restores exactly this state with `intelligence sync`. packages: "@ainova-systems/sync": - version: "0.18.1" + version: "0.19.0" # A package resolved through the trust list below — the name is all the # manifest needs, the registry supplies the url. "@org/shared-intel": diff --git a/intelligence.lock b/intelligence.lock index b4cf462..5b7d150 100644 --- a/intelligence.lock +++ b/intelligence.lock @@ -1,6 +1,6 @@ # Generated by the intelligence CLI. Do not edit. lockfile_version: 1 -engine_version: "0.18.1" +engine_version: "0.19.0" packages: "@ainova-systems/core": requested: "^0.9.3" @@ -9,8 +9,8 @@ packages: resolved: "v0.9.3" sha: "75fca75f2aa40e8d8b738131ec39714af4ea7863" "@ainova-systems/sync": - requested: "0.18.1" + requested: "0.19.0" url: "https://github.com/ainova-systems/intelligence.git" path: "packages/sync" - resolved: "v0.18.1" + resolved: "v0.19.0" sha: "" diff --git a/intelligence.yaml b/intelligence.yaml index bc87d8f..92eee8d 100644 --- a/intelligence.yaml +++ b/intelligence.yaml @@ -4,7 +4,7 @@ project: name: "intelligence" # Schema version of this manifest. The CLI keeps it in step with its engine. -schema_version: "0.18.1" +schema_version: "0.19.0" # Where content comes from. Nothing here has to exist: a directory that is # absent is skipped, so a project consuming only packages authors nothing of @@ -66,6 +66,6 @@ registries: packages: "@ainova-systems/sync": - version: "0.18.1" + version: "0.19.0" "@ainova-systems/core": version: "^0.9.3"