diff --git a/FIXDRY.md b/FIXDRY.md deleted file mode 100644 index cd9e46e5..00000000 --- a/FIXDRY.md +++ /dev/null @@ -1,40 +0,0 @@ -# DRY / low-code replacement audit - -This file tracks places where OpenLogi carries general-purpose infrastructure code that can be replaced by mature crates. The goal is not to add dependencies for their own sake, but to delete code where an external crate is a better source of truth. - -## Low-risk replacements to do first - -- [x] Replace `xtask`'s custom temporary-directory guard with `tempfile`. -- [x] Replace `xtask`'s custom `PATH` scanning with `which`. -- [x] Replace macOS LaunchAgent plist string rendering / XML escaping with `plist`. -- [x] Replace hand-built GUI `file://` URLs with `url::Url::from_file_path`. - -## Worth doing next - -- [x] Replace `openlogi-assets::http::write_replace` with `atomic-write-file`, preserving atomic replacement and symlink safety. -- [x] Replace recursive asset-cache directory walking with `walkdir`. -- [x] Replace `xtask` command orchestration with `xshell`. -- [x] Replace stale-agent process discovery/signalling through `pgrep`/`kill` with `sysinfo`. -- [x] Replace `xtask` file/path helpers with `fs-err` and `path-absolutize`. -- [x] Replace remaining `xtask` production file operations with `fs-err`. -- [x] Replace `xtask`'s hand-written SHA-256 file loop with `sha2_hasher`. -- [x] Replace `xtask` manifest tests' custom temp directory with `tempfile`. -- [x] Replace macOS iconset shell-out (`sips` + `iconutil`) with `image` + `icns`. -- [x] Replace GUI asset-sync retry delay math with `backon`'s exponential backoff. -- [x] Replace generic GUI/agent `open` shell-outs with `opener`. - -## Needs behavior tests before replacing - -- [x] Evaluate `etcetera` for XDG-style config/data/runtime paths. Adopted `etcetera::base_strategy::Xdg`, not platform-native macOS paths. -- [x] Evaluate `fluent-langneg` for locale matching, while keeping OpenLogi's shipped-locale policy for Chinese, Portuguese, and Norwegian variants. - -## Keep custom for now - -- `openlogi-core::single_instance`: `single-instance` uses different backends (for example abstract Unix sockets on Linux) and does not preserve OpenLogi's data-dir lock-file path, per-role names, and error classification closely enough to be a safe deletion. -- Agent tray Quit's `openlogi://quit` dispatch keeps `std::process::Command::output()` intentionally: it blocks until LaunchServices accepts the Apple Event, while generic opener crates only guarantee process spawn. -- GUI helper launch keeps `/usr/bin/open -g -n` intentionally: it needs LaunchServices-specific flags to start the packaged agent under its own TCC identity, which generic opener crates do not expose. -- Agent autostart install keeps direct `systemctl` calls because it is managing systemd user units, not merely opening or spawning an arbitrary program. -- Self-restart and `disclaim` launches stay custom because they are process identity / update lifecycle boundaries, not generic command orchestration. -- `openlogi-hook`: event suppression/rewriting and foreground-app lookup are OpenLogi-specific and not covered cleanly by generic input crates. -- `openlogi-inject`: platform-specific action synthesis may overlap with `enigo`, but current semantics are narrower and more controlled. -- `openlogi-hid` / vendored `openlogi-hidpp`: the right path is upstreaming OpenLogi-specific fixes, not replacing the fork blindly. diff --git a/devenv.lock b/devenv.lock index 9fc0737c..8bf78b3a 100644 --- a/devenv.lock +++ b/devenv.lock @@ -67,11 +67,11 @@ ] }, "locked": { - "lastModified": 1779592685, - "narHash": "sha256-p9d56GezhHRf4QfANxwa1d+fvwShvjB5XUhdIl7WEd0=", + "lastModified": 1783144302, + "narHash": "sha256-NQnzmXwpEAd5tjMBh2+P/y9NknF+WHv5+6yoXoN4h/Y=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "3a58b199e7c83a80b85c28044f808085ba7e941c", + "rev": "fe5aee0952e8e1525533d61defd9e36513db811b", "type": "github" }, "original": { diff --git a/docs/DECISIONS.md b/docs/DECISIONS.md new file mode 100644 index 00000000..d060866a --- /dev/null +++ b/docs/DECISIONS.md @@ -0,0 +1,34 @@ +# Decision log + +Durable "why we did it this way" records that are not obvious from the code. +Add a dated entry when a non-obvious architectural or dependency decision is +made or revisited. + +## 2026-07: Infrastructure we keep custom instead of using a crate + +A dependency audit replaced most general-purpose infrastructure code with +mature crates (`tempfile`, `which`, `plist`, `walkdir`, `xshell`, `sysinfo`, +`fs-err`, `backon`, `opener`, `etcetera`, and others — see the git history of +`FIXDRY.md` for the full list). The following stayed custom, deliberately: + +- `openlogi-core::single_instance`: the `single-instance` crate uses different + backends (for example abstract Unix sockets on Linux) and does not preserve + OpenLogi's data-dir lock-file path, per-role names, and error classification + closely enough to be a safe deletion. +- Agent tray Quit's `openlogi://quit` dispatch keeps + `std::process::Command::output()` intentionally: it blocks until + LaunchServices accepts the Apple Event, while generic opener crates only + guarantee process spawn. +- GUI helper launch keeps `/usr/bin/open -g -n` intentionally: it needs + LaunchServices-specific flags to start the packaged agent under its own TCC + identity, which generic opener crates do not expose. +- Agent autostart install keeps direct `systemctl` calls because it is managing + systemd user units, not merely opening or spawning an arbitrary program. +- Self-restart and `disclaim` launches stay custom because they are process + identity / update lifecycle boundaries, not generic command orchestration. +- `openlogi-hook`: event suppression/rewriting and foreground-app lookup are + OpenLogi-specific and not covered cleanly by generic input crates. +- `openlogi-inject`: platform-specific action synthesis may overlap with + `enigo`, but current semantics are narrower and more controlled. +- `openlogi-hid` / vendored `openlogi-hidpp`: the right path is upstreaming + OpenLogi-specific fixes, not replacing the fork blindly.