This directory contains the .NET port of the session-recall CLI tool.
Parity tested against Python 3.13.7 (session-recall v0.1.0)
This .NET port is feature-equivalent to the Python reference implementation. All commands, options, exit codes, and JSON output formats match byte-for-byte (modulo timestamp/duration fields). See net/tests/Parity for the test harness.
- AutoMemory.Core: Core library with database access, configuration, search, health checks, and utilities
- AutoMemory.Cli: Command-line interface executable (output:
session-recall) - AutoMemory.Tests: xUnit test suite
dotnet build net/AutoMemory.sln -c Releasedotnet test net/AutoMemory.sln -c ReleaseThe CLI is configured for single-file, self-contained, trimmed publishing:
dotnet publish net/src/AutoMemory.Cli/AutoMemory.Cli.csproj \
-c Release \
-r linux-x64 \
--self-contained \
-o ./publishSupported RIDs: linux-x64, win-x64, osx-arm64
For users requiring database encryption at rest, an opt-in build with SQLCipher is available:
dotnet publish net/src/AutoMemory.Cli/AutoMemory.Cli.csproj \
-c Release \
-r linux-x64 \
-p:UseEncryptedSqlite=true \
--self-contained \
-o ./publish-encryptedSee docs/encrypted-build.md for encryption setup and usage.
Decision: Stay on single-file trimmed; do not adopt PublishAot.
-
Build complexity: AOT requires platform-specific C++ build tools (Visual Studio C++ workload on Windows, clang on Linux/macOS), adding significant developer and CI overhead.
-
Cross-compilation limitation: AOT does not support cross-OS compilation. Building Linux binaries requires a Linux build agent, Windows binaries require Windows, etc. The current single-file approach works across platforms from any host.
-
Size budget met: Current single-file trimmed binary for linux-x64 is ~13.4 MB, well under the 25 MB budget.
-
Cold-start performance: The session-recall tool primarily interacts with SQLite I/O. Cold-start savings from AOT would be minimal compared to database access time. For a CLI tool run interactively (not in tight loops), the current startup time is acceptable.
-
Toolchain simplicity: Staying on single-file trimmed keeps the build process simple (
dotnet publish) with no external dependencies beyond the .NET SDK.
Reevaluate AOT if:
- Cold-start profiling shows ≥100ms is spent in .NET JIT/startup (vs I/O)
- GitHub Actions adds native AOT build matrix support
- Microsoft.Data.Sqlite publishes trim/AOT compatibility guidance
- User feedback indicates startup time is a pain point
See AutoMemory.Cli.csproj:
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>partial</TrimMode>
<InvariantGlobalization>true</InvariantGlobalization>
<DebugType>embedded</DebugType>
<EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
<TieredPGO>true</TieredPGO>
<PublishReadyToRun>true</PublishReadyToRun>No additional [DynamicDependency] annotations are required with TrimMode=partial.
Decision: Enable TieredPGO and PublishReadyToRun by default.
Benchmarked on Windows x64 with hyperfine --warmup 2 --runs 20:
- Baseline: 311.3ms mean (single-file trimmed, no PGO/R2R)
- Optimized: 163.9ms mean (with PGO/R2R)
- Improvement: 47% reduction in cold-start time
- Binary size: Increases from ~13.4 MB to ~15.6 MB (+16%) due to ReadyToRun's pre-compiled native code
- Still under budget: Well below the 25 MB target
- Build time: Minimal increase (~1-2 seconds per publish)
- Compatibility: Works with single-file trimmed publishing (unlike AOT which was rejected)
- TieredPGO: Dynamic Profile-Guided Optimization learns hot paths at runtime and recompiles them
- PublishReadyToRun: Pre-compiles common .NET libraries to native code, reducing JIT work at startup
See hyperfine-results.md for full benchmark data.