chore: release - #193
Conversation
Deploying soar-docs with
|
| Latest commit: |
df2a2b3
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://d9562c3a.soar-docs.pages.dev |
| Branch Preview URL: | https://release-plz-2026-08-10t11-04.soar-docs.pages.dev |
📝 WalkthroughWalkthroughThe CLI now supports structured JSON output, JSON event streams, update checks, environment serialization, and a generated plugin manifest. Event serialization, database connection preparation, maintainer lookup, package versions, and release changelogs were also updated. ChangesFrontend integration
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Frontend
participant SoarCLI
participant SoarContext
participant JsonLinesSink
Frontend->>SoarCLI: invoke command with --json
SoarCLI->>SoarContext: create context for document or event output
SoarContext->>JsonLinesSink: route events to stdout or stderr
SoarCLI-->>Frontend: emit JSON document or JSON listing
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (2)
crates/soar-cli/src/plugin_manifest.rs (1)
260-283: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExtend the test to check flags, not only subcommand names.
every_operation_names_a_real_subcommandvalidates the first non-flag argument only. The manifest also hardcodes flags such as--check,--dry-run,--prune,--yesand the global--json. If any of these flags is renamed or removed, the manifest silently breaks the frontend contract while the test still passes. Clap exposesget_arguments()per subcommand, so the same introspection can validate each long flag.♻️ Sketch for flag validation
for (op, table) in parsed["ops"].as_table().expect("ops table") { let args: Vec<&str> = table["args"] .as_array() .expect("args array") .iter() .filter_map(|a| a.as_str()) .collect(); let subcommand = args .iter() .find(|a| !a.starts_with('-')) .unwrap_or_else(|| panic!("{op} names no subcommand")); let cmd = crate::cli::Args::command(); let global: Vec<String> = cmd .get_arguments() .filter_map(|a| a.get_long().map(String::from)) .collect(); let sub = cmd .find_subcommand(subcommand) .unwrap_or_else(|| panic!("{op} runs `{subcommand}`, which this soar does not have")); let local: Vec<String> = sub .get_arguments() .filter_map(|a| a.get_long().map(String::from)) .collect(); for flag in args.iter().filter_map(|a| a.strip_prefix("--")) { assert!( global.iter().chain(local.iter()).any(|k| k == flag), "{op} passes `--{flag}`, which `{subcommand}` does not accept" ); } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/soar-cli/src/plugin_manifest.rs` around lines 260 - 283, Extend every_operation_names_a_real_subcommand to collect each operation’s string arguments, then validate every long flag against Clap’s global arguments from Args::command().get_arguments() and the selected subcommand’s arguments from find_subcommand(). Preserve the existing subcommand validation and report the operation, flag, and subcommand when a manifest flag is unsupported.crates/soar-operations/src/search.rs (1)
351-355: 🚀 Performance & Scalability | 🔵 Trivial | 🏗️ Heavy liftBatch maintainer lookups by repository.
When a query returns many packages, Lines 353-355 execute one
MetadataRepository::get_maintainersquery for each package. The supplied implementation incrates/soar-db/src/repository/metadata.rs, Lines 414-426, loads maintainers for onepackage_id, so this adds an N+1 query pattern toquery_package. Group package IDs by repository and load the mappings in one query per repository.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/soar-operations/src/search.rs` around lines 351 - 355, Replace the per-package MetadataRepository::get_maintainers call in query_package with repository-grouped batch lookups: collect package IDs by repo_name, execute one maintainer query per repository, then apply each returned mapping to the corresponding packages while preserving existing maintainer data behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/soar-cli/src/plugin_manifest.rs`:
- Around line 30-33: Update the generated manifest’s [detect] min_version value
instead of reusing `@version`@, setting it to the oldest soar release compatible
with this schema. Keep the version field tied to CARGO_PKG_VERSION while
ensuring independently upgraded soar versions remain accepted.
- Around line 235-246: The manifest function currently formats profile names
with Rust debug syntax, which can produce invalid TOML; serialize profiles using
TOML-compatible values or escaping before replacing `@profiles`@. Update the
profile-list construction in manifest while preserving the existing empty-list
and comma-separated template substitution behavior.
In `@crates/soar-core/CHANGELOG.md`:
- Line 6: Update the changelog entry for the local package updates to replace
the placeholder 0000000 link with the actual commit hash, or remove the commit
link if no valid hash is available.
In `@crates/soar-db/src/connection.rs`:
- Around line 33-38: Update the WAL setup in the connection initialization flow
to use get_result instead of execute, capture the returned journal-mode string,
and verify that it is WAL before emitting the success trace. If SQLite reports a
different mode, handle it as a connection error before migrations proceed.
In `@crates/soar-events/CHANGELOG.md`:
- Around line 2-6: Update the 0.3.0 entry in CHANGELOG.md to document the
breaking SoarEvent API changes: SoarEvent::Log now uses discriminant 20 instead
of 19, and SoarEvent::ApplyComplete is newly added. Explicitly state that
exhaustive matches and discriminant-based consumers must migrate before
upgrading.
In `@crates/soar-operations/src/apply.rs`:
- Around line 364-369: Update the package configuration update error paths in
the apply flow—each PackagesConfig::update_package failure around the
installation, update, and removal handling—to increment failed_count before
logging/continuing, then emit the resulting value through ApplyComplete.
Preserve existing handling for successful writes and other operation failures.
In `@crates/soar-operations/src/search.rs`:
- Around line 353-371: Handle errors from the maintainer lookup in the
enrichment flow around metadata_mgr.query_repo instead of discarding them
through if let Ok(Some(...)). Either propagate the query error, or if enrichment
remains best-effort, log it with package.repo_name and package.id while
preserving the existing handling for successful Some and None results.
---
Nitpick comments:
In `@crates/soar-cli/src/plugin_manifest.rs`:
- Around line 260-283: Extend every_operation_names_a_real_subcommand to collect
each operation’s string arguments, then validate every long flag against Clap’s
global arguments from Args::command().get_arguments() and the selected
subcommand’s arguments from find_subcommand(). Preserve the existing subcommand
validation and report the operation, flag, and subcommand when a manifest flag
is unsupported.
In `@crates/soar-operations/src/search.rs`:
- Around line 351-355: Replace the per-package
MetadataRepository::get_maintainers call in query_package with
repository-grouped batch lookups: collect package IDs by repo_name, execute one
maintainer query per repository, then apply each returned mapping to the
corresponding packages while preserving existing maintainer data behavior.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 2018967a-74c5-4642-911e-81895294b305
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (29)
CHANGELOG.mdCargo.tomlcrates/soar-cli/Cargo.tomlcrates/soar-cli/src/apply.rscrates/soar-cli/src/cli.rscrates/soar-cli/src/json_output.rscrates/soar-cli/src/list.rscrates/soar-cli/src/logging.rscrates/soar-cli/src/main.rscrates/soar-cli/src/plugin_manifest.rscrates/soar-cli/src/repo.rscrates/soar-cli/src/update.rscrates/soar-cli/src/utils.rscrates/soar-core/CHANGELOG.mdcrates/soar-core/Cargo.tomlcrates/soar-db/CHANGELOG.mdcrates/soar-db/Cargo.tomlcrates/soar-db/src/connection.rscrates/soar-events/CHANGELOG.mdcrates/soar-events/Cargo.tomlcrates/soar-events/src/event.rscrates/soar-events/src/sink.rscrates/soar-operations/CHANGELOG.mdcrates/soar-operations/Cargo.tomlcrates/soar-operations/src/apply.rscrates/soar-operations/src/search.rscrates/soar-registry/CHANGELOG.mdcrates/soar-registry/Cargo.tomlcrates/soar-registry/src/package.rs
💤 Files with no reviewable changes (1)
- crates/soar-registry/src/package.rs
| [detect] | ||
| command = "soar" | ||
| version = ["--version"] | ||
| min_version = "@version@" |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
min_version repeats the emitting binary version.
Line 17 sets version to CARGO_PKG_VERSION. Line 33 sets min_version to the same value. A frontend that compares its installed soar against min_version therefore accepts only that version or newer, which is stricter than the real requirement. State the oldest soar release that satisfies this schema instead, so the manifest stays usable when soar is upgraded independently of the frontend.
🐛 Proposed fix
+/// The oldest soar that answers the commands in this manifest.
+const MIN_VERSION: &str = "0.13.2";
+ [detect]
command = "soar"
version = ["--version"]
-min_version = "`@version`@"
+min_version = "`@min_version`@" TEMPLATE
.replace("`@schema_version`@", &SCHEMA_VERSION.to_string())
.replace("`@version`@", env!("CARGO_PKG_VERSION"))
+ .replace("`@min_version`@", MIN_VERSION)
.replace("`@profiles`@", &options)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/soar-cli/src/plugin_manifest.rs` around lines 30 - 33, Update the
generated manifest’s [detect] min_version value instead of reusing `@version`@,
setting it to the oldest soar release compatible with this schema. Keep the
version field tied to CARGO_PKG_VERSION while ensuring independently upgraded
soar versions remain accepted.
| pub fn manifest(profiles: &[String]) -> String { | ||
| let options = profiles | ||
| .iter() | ||
| .map(|profile| format!("{profile:?}")) | ||
| .collect::<Vec<_>>() | ||
| .join(", "); | ||
|
|
||
| TEMPLATE | ||
| .replace("@schema_version@", &SCHEMA_VERSION.to_string()) | ||
| .replace("@version@", env!("CARGO_PKG_VERSION")) | ||
| .replace("@profiles@", &options) | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
Rust String Debug escaping rules versus TOML basic string escape sequences
💡 Result:
Rust's String Debug escaping and TOML's basic string escape sequences are distinct mechanisms with different purposes, resulting in notable differences in their implementation. Rust Debug Escaping Rust's str::escape_debug (used by the Debug trait) is intended for diagnostic output, aiming to make hidden characters visible [1]. Its primary rules are: - It escapes non-printable ASCII characters and most non-printable Unicode characters (including control characters, some separators, and unassigned characters) [2]. - It commonly represents these using either compact escape sequences (e.g., \t, \r, \n) or hexadecimal Unicode escapes (e.g., \u{XXXX}) [2]. - It does not strictly define a single standard across all versions, as implementation details—such as the handling of combining characters or single quotes—have evolved and occasionally been flagged as inconsistent [3][4]. - It is designed to be human-readable for debugging rather than as a strict data-interchange format [1]. TOML Basic String Escaping TOML v1.0.0 defines strict, interoperable rules for basic string escape sequences [5][6]. A TOML-compliant parser must handle the following specific sequences: - Compact escapes: \b (backspace, U+0008), \t (tab, U+0009), \n (linefeed, U+000A), \f (form feed, U+000C), \r (carriage return, U+000D), " (quote, U+0022), and \ (backslash, U+005C) [5][6]. - Unicode escapes: \uXXXX (4-digit hex) and \UXXXXXXXX (8-digit hex), which must represent valid Unicode scalar values [5][6]. - Any other escape sequence starting with a backslash is reserved and results in a parsing error [5][6]. Key Differences - Strictness: TOML is a formal specification where unknown backslash-escapes are errors [5][6]. Rust's escape_debug is an implementation detail for developer visibility, not a strict grammar [1][2]. - Compatibility: While there is some overlap (e.g., \t, \n, \r, \), they are not identical. Rust's escape_debug does not produce TOML-compliant output by default. For instance, Rust may output \u{XXXX} (braced), while TOML requires \uXXXX (unbraced) [3][5]. Furthermore, Rust's escape_debug may escape single quotes (depending on context), whereas TOML basic strings do not require or provide a standard escape for single quotes [3][5]. - Purpose: Rust's method prioritizes visibility of potentially problematic characters (like invisible separators), while TOML prioritizes data integrity and successful deserialization [1][5].
Citations:
- 1: https://rust-lang.github.io/rfcs/0565-show-string-guidelines.html
- 2: Escape fewer Unicode codepoints in
Debugimpl ofstrrust-lang/rust#34485 - 3: Debug escaping is confusingly inconsistent rust-lang/rust#107035
- 4: Escape combining characters in char::Debug rust-lang/rust#49283
- 5: https://toml.io/en/v1.0.0
- 6: https://github.com/toml-lang/toml.io/blob/main/specs/en/v1.0.0.md
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Files matching manifest/toml:"
fd -a 'manifest|Cargo' . | sed 's#^\./##' | head -80
echo
echo "Locate plugin_manifest.rs:"
fd -a 'plugin_manifest\.rs' . | sed 's#^\./##'
echo
echo "Relevant file outline/section:"
file="$(fd 'plugin_manifest\.rs' . | head -1)"
if [ -n "${file:-}" ]; then
wc -l "$file"
sed -n '200,260p' "$file" | nl -ba -v200
fi
echo
echo "Cargo toml dependency declarations:"
rg -n 'toml\s*=' Cargo.toml crates -g 'Cargo.toml' || true
echo
echo "Search for manifest/profile usage:"
rg -n 'profile|manifest\(|manifests|`@profiles`@' crates/soar-cli Cargo.toml -g '*.rs' -g 'Cargo.toml' || trueRepository: pkgforge/soar
Length of output: 986
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import json, re, subprocess
# Read-only behavioral probe: determine whether this Rust repo has toml toolchain available
# and exercise serde_d2 if present; do not modify repository files.
PYRepository: pkgforge/soar
Length of output: 151
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "plugin_manifest.rs relevant section:"
sed -n '200,270p' crates/soar-cli/src/plugin_manifest.rs
echo
echo "Cargo manifest dependencies mentioning toml:"
rg -n 'toml(\s+|\.|\|)|serde( |_toml)?|crate-type|dev-dependencies|build-dependencies' Cargo.toml crates -g 'Cargo.toml' || true
echo
echo "Check installed Rust tools:"
(command -v cargo && cargo --version) || true
(command -v rustc && rustc --version) || true
echo
echo "If cargo is available, compile a Rust Stdlib behavior probe for String Debug escaping:"
if [ "$(command -v cargo 2>/dev/null)" != "" ]; then
tmp="$(mktemp -d)"
cargo new --quiet "$tmp"
cat > "$tmp/src/main.rs" <<'RS'
fn main() {
for s in ["profile", "profile\n", "profile\t", "profile\u{A0}", "profile\u{200B}"] {
let quote = format!("{:?}", s);
println!("{:?}\t{:?}", s, quote);
}
}
RS
(cd "$tmp" && cargo run --quiet 2>&1 | sed -n '1,80p')
rm -rf "$tmp"
fiRepository: pkgforge/soar
Length of output: 5035
Serialize the profile list into TOML instead of using format!("{profile:?}").
{profile:?} emits Rust debug output, not TOML string content. TOML and Rust Debug escape sequences can differ; for example, TOML basic strings use \uXXXX, while Rust Debug uses braced Unicode escapes such as \u{XXXX}. A profile name containing such a character can make the manifest invalid TOML. Use toml::value::Value::Array or TOML escaping before replacing @profiles@.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/soar-cli/src/plugin_manifest.rs` around lines 235 - 246, The manifest
function currently formats profile names with Rust debug syntax, which can
produce invalid TOML; serialize profiles using TOML-compatible values or
escaping before replacing `@profiles`@. Update the profile-list construction in
manifest while preserving the existing empty-list and comma-separated template
substitution behavior.
|
|
||
| ### ⚙️ Miscellaneous Tasks | ||
|
|
||
| - Updated the following local packages: soar-db, soar-events - ([0000000](https://github.com/pkgforge/soar/commit/0000000)) |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Tracked CHANGELOG files:"
git ls-files | grep -E '(^|/)CHANGELOG\.md$' | sed -n '1,50p'
echo
echo "Crates soar-core CHANGELOG first lines:"
if [ -f crates/soar-core/CHANGELOG.md ]; then
nl -ba crates/soar-core/CHANGELOG.md | sed -n '1,20p'
else
echo "crates/soar-core/CHANGELOG.md not found"
fi
echo
echo "Occurrences of 0000000 in tracked files:"
rg -n --hidden --glob '!target/**' '0000000' . || true
echo
echo "SHA validity check for placeholder:"
python3 - <<'PY'
import subprocess
result = subprocess.run(['git', 'cat-file', '-e', '0000000'], capture_output=True, text=True, check=False)
print(f"git cat-file -e 0000000 exit code={result.returncode}")
print(result.stderr)
PYRepository: pkgforge/soar
Length of output: 555
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Crates soar-core CHANGELOG context:"
if [ -f crates/soar-core/CHANGELOG.md ]; then
sed -n '1,25p' crates/soar-core/CHANGELOG.md
else
echo "crates/soar-core/CHANGELOG.md not found"
fi
echo
echo "Occurrences of 0000000 in tracked files:"
if command -v rg >/dev/null 2>&1; then
rg -n --hidden --glob '!target/**' '0000000' . || true
else
grep -RIn --exclude-dir=target '0000000' . || true
fi
echo
echo "SHA validity check for placeholder:"
if command -v git >/dev/null 2>&1; then
git cat-file -e 0000000
echo exit="$?"
elif command -v gsha1sum >/dev/null 2>&1; then
printf '0000000' | gsha1sum
else
echo "no git or gsha1sum available"
fiRepository: pkgforge/soar
Length of output: 6377
Replace the placeholder commit hash.
0000000 is not a valid commit and makes this changelog link return a 404. Replace it with the actual commit hash or remove the link before publishing.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/soar-core/CHANGELOG.md` at line 6, Update the changelog entry for the
local package updates to replace the placeholder 0000000 link with the actual
commit hash, or remove the commit link if no valid hash is available.
| // WAL mode for better concurrent access | ||
| sql_query("PRAGMA journal_mode = WAL;") | ||
| .execute(conn) | ||
| .map_err(|e| ConnectionError::BadConnection(e.to_string()))?; | ||
|
|
||
| trace!("busy timeout and WAL journal mode set"); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n 'diesel' --glob 'Cargo.toml' --glob 'Cargo.lock' || true
rg -n -C 4 'PRAGMA (busy_timeout|journal_mode)|sql_query|batch_execute' \
crates/soar-db/src/connection.rs
if command -v sqlite3 >/dev/null 2>&1; then
mode="$(sqlite3 ':memory:' 'PRAGMA journal_mode = WAL;')"
printf 'in-memory journal mode: %s\n' "$mode"
test "$mode" = "memory"
fiRepository: pkgforge/soar
Length of output: 151
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Repo files of interest:\n'
git ls-files | rg '(^Cargo\.(toml|lock)$|crates/soar-db/src/connection\.rs$|Cargo\.cargo\.toml$|\.cargo/config\.toml$)' || true
printf '\nconnection.rs outline:\n'
ast-grep outline crates/soar-db/src/connection.rs --view expanded || true
printf '\nconnection.rs relevant lines:\n'
cat -n crates/soar-db/src/connection.rs | sed -n '1,180p'
printf '\nDiesel entries:\n'
for f in Cargo.toml Cargo.lock crates/soar-db/Cargo.toml; do
if [ -f "$f" ]; then
echo "--- $f"
rg -n -C 3 'diesel|sqlite|rusqlite' "$f" || true
fi
done
if command -v sqlite3 >/dev/null 2>&; then
printf '\nSQLite PRAGMA mode behavior examples:\n'
for file in ':memory:' '/tmp/test-journalmode.db' '/tmp/test-journalmode.db-wal'; do
rm -f "/tmp/test-journalmode.db"{,} "-shm" "-wal" 2>/dev/null || true
done
for pragma in 'PRAGMA journal_mode = WAL;' 'PRAGMA journal_mode = DELETE;' 'PRAGMA journal_mode'; do
printf 'PRAGMA: %s => ' "$pragma"
sqlite3 ':memory:' "$pragma"
done
sqlite3 /tmp/test-journalmode.db-wb "PRAGMA journal_mode = WAL; SELECT 'after switch:' || (SELECT page_count FROM pragma_page_count); PRAGMA journal_mode;" rm -f /tmp/test-journalmode.db-wb* 2>/dev/null || true
fiRepository: pkgforge/soar
Length of output: 12998
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'SQLite PRAGMA mode behavior examples:\n'
for file in '/tmp/test-journalmode.db' '/tmp/test-journalmode.db-wal'; do
rm -f "$file"{,-shm,-wal} 2>/dev/null || true
done
for mode in delete memory wal; do
file="/tmp/test-journalmode-$mode.db"
rm -f "${file}"{,-shm,-wal} 2>/dev/null || true
current="$(sqlite3 "$file" "PRAGMA journal_mode; PRAGMA journal_mode = WAL; PRAGMA journal_mode = DELETE;")"
printf 'initial=%s current after set-wal=%s final=%s\n' "$mode" "$current"
rm -f "${file}"{,-shm,-wal} 2>/dev/null || true
done
# Try to read the returned value as Diesel can via .get_result(), without using repo code or creating files.
python3 - <<'PY'
import sqlite3
conn = sqlite3.connect(":memory:")
row = conn.execute("PRAGMA journal_mode = WAL;").fetchone()
print("PRAGMA row:", row)
print("effective_mode:", row[0] if row else None)
PYRepository: pkgforge/soar
Length of output: 235
🌐 Web query:
SQLite PRAGMA journal_mode documentation returns journal mode
💡 Result:
The SQLite PRAGMA journal_mode command is used to query or set the journaling mode for the current database connection [1][2][3]. When executed, the pragma returns a string representing the journal mode that is currently in effect [4][5]. When used to query the current mode, the pragma returns the string value of the active journal mode (e.g., "delete", "wal", "truncate", "persist", "memory", or "off") [1][4][3]. When used to set a new journal mode (e.g., PRAGMA journal_mode = WAL;), the pragma also returns a string [4]. On success, this returned string is the new journal mode (e.g., "wal") [4][5]. If the requested conversion cannot be completed—for example, if the VFS lacks necessary support—the journaling mode remains unchanged, and the pragma returns the string of the prior (existing) journaling mode [4][5].
Citations:
- 1: https://sqlite.org/pragma.html
- 2: https://sqlite.org/draft/pragma.html
- 3: https://www.oreilly.com/library/view/using-sqlite/9781449394592/re185.html
- 4: https://www.sqlite.org/wal.html
- 5: http://code.djangoproject.com/ticket/24018
Check the returned journal mode before tracing WAL setup.
PRAGMA journal_mode = WAL returns the journal mode in effect. If SQLite cannot switch to WAL, it returns the previous mode and keeps that mode. The current .execute() call discards this value, so the trace can report WAL mode while operations later run under a different journal mode. Use .get_result(...) to inspect the returned string and fail or handle the fallback before migrations.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/soar-db/src/connection.rs` around lines 33 - 38, Update the WAL setup
in the connection initialization flow to use get_result instead of execute,
capture the returned journal-mode string, and verify that it is WAL before
emitting the success trace. If SQLite reports a different mode, handle it as a
connection error before migrations proceed.
Source: MCP tools
| ## [0.3.0](https://github.com/pkgforge/soar/compare/soar-events-v0.2.0...soar-events-v0.3.0) - 2026-08-10 | ||
|
|
||
| ### ⛰️ Features | ||
|
|
||
| - *(cli)* Expose soar to frontends with JSON output and a plugin manifest ([#192](https://github.com/pkgforge/soar/pull/192)) - ([1ea7f51](https://github.com/pkgforge/soar/commit/1ea7f51c854c007de53b734de5a3892baaba2c2e)) |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Document the breaking soar-events API changes.
The 0.3.0 entry only lists the frontend feature. Add the SoarEvent::Log discriminant change from 19 to 20 and the new SoarEvent::ApplyComplete variant. State that exhaustive matches and discriminant-based consumers require migration before upgrade.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/soar-events/CHANGELOG.md` around lines 2 - 6, Update the 0.3.0 entry
in CHANGELOG.md to document the breaking SoarEvent API changes: SoarEvent::Log
now uses discriminant 20 instead of 19, and SoarEvent::ApplyComplete is newly
added. Explicitly state that exhaustive matches and discriminant-based consumers
must migrate before upgrading.
| ctx.events().emit(SoarEvent::ApplyComplete { | ||
| installed: installed_count, | ||
| updated: updated_count, | ||
| removed: removed_count, | ||
| failed: failed_count, | ||
| }); |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Count configuration-write failures in ApplyComplete.
failed_count increases only from installation and removal reports. The PackagesConfig::update_package failures at Lines 224-229, 267-273, and 313-319 are logged but do not change failed_count. A failed write can therefore produce failed: 0 while packages.toml remains stale. Increment failed_count for these failures, or add a separate configuration-write failure field before emitting ApplyComplete.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/soar-operations/src/apply.rs` around lines 364 - 369, Update the
package configuration update error paths in the apply flow—each
PackagesConfig::update_package failure around the installation, update, and
removal handling—to increment failed_count before logging/continuing, then emit
the resulting value through ApplyComplete. Preserve existing handling for
successful writes and other operation failures.
| let found = metadata_mgr.query_repo(&package.repo_name, |conn| { | ||
| MetadataRepository::get_maintainers(conn, package.id as i32) | ||
| }); | ||
|
|
||
| if let Ok(Some(maintainers)) = found { | ||
| let named: Vec<_> = maintainers | ||
| .into_iter() | ||
| .map(|m| { | ||
| soar_core::database::models::Maintainer { | ||
| name: m.name, | ||
| contact: m.contact, | ||
| } | ||
| }) | ||
| .collect(); | ||
|
|
||
| if !named.is_empty() { | ||
| package.maintainers = Some(named); | ||
| } | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
Do not silently convert maintainer lookup errors into missing data.
The if let Ok(Some(...)) condition drops every Err from metadata_mgr.query_repo. A lock or schema error then returns a package without maintainers, and JSON consumers cannot distinguish that result from a package with no maintainers. If best-effort enrichment is intentional, log the error with package.repo_name and package.id; otherwise propagate it.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/soar-operations/src/search.rs` around lines 353 - 371, Handle errors
from the maintainer lookup in the enrichment flow around metadata_mgr.query_repo
instead of discarding them through if let Ok(Some(...)). Either propagate the
query error, or if enrichment remains best-effort, log it with package.repo_name
and package.id while preserving the existing handling for successful Some and
None results.
🤖 New release
soar-registry: 0.6.1 -> 0.6.2 (✓ API compatible changes)soar-db: 0.6.1 -> 0.6.2 (✓ API compatible changes)soar-events: 0.2.0 -> 0.3.0 (⚠ API breaking changes)soar-operations: 0.4.1 -> 0.4.2 (✓ API compatible changes)soar-cli: 0.13.1 -> 0.13.2soar-core: 0.17.1 -> 0.17.2⚠
soar-eventsbreaking changesChangelog
soar-registrysoar-dbsoar-eventssoar-operationssoar-clisoar-coreThis PR was generated with release-plz.
Summary by CodeRabbit
New Features
--jsonoutput for package searches, listings, details, repositories, environment information, updates, and apply results.plugin-manifestcommand for frontend integrations.update --checkto preview pending updates without making changes.Bug Fixes