diff --git a/flake.nix b/flake.nix index 54fd0acef..e13f686bb 100644 --- a/flake.nix +++ b/flake.nix @@ -125,7 +125,7 @@ type = pkgs.lib.types.listOf pkgs.lib.types.package; default = [ ]; }; - options.home.file = pkgs.lib.mkOption { + options.home.activation = pkgs.lib.mkOption { type = pkgs.lib.types.attrsOf pkgs.lib.types.anything; default = { }; }; @@ -152,7 +152,7 @@ }; modulesEvaluate = assert builtins.elem self.packages.${system}.default homeManagerEvaluation.config.home.packages; - assert homeManagerEvaluation.config.home.file ? ".omp/agent/config.yml"; + assert homeManagerEvaluation.config.home.activation ? ompConfig; assert builtins.elem self.packages.${system}.default nixosEvaluation.config.environment.systemPackages; pkgs.runCommand "omp-module-evaluation" { } "touch $out"; diff --git a/nix/home-manager.nix b/nix/home-manager.nix index 9f74df866..e8f30d3ae 100644 --- a/nix/home-manager.nix +++ b/nix/home-manager.nix @@ -8,6 +8,7 @@ let cfg = config.programs.omp; yaml = pkgs.formats.yaml { }; + configFile = yaml.generate "omp-config.yml" cfg.settings; in { options.programs.omp = { @@ -25,8 +26,11 @@ in default = null; description = '' Settings written declaratively to {file}`~/.omp/agent/config.yml`. - The file is a read-only store symlink: changes made from inside OMP - (`/settings`, onboarding) replace it but revert on the next + On each `home-manager switch` the declared settings are copied into + place as a writable regular file (not a read-only store symlink), so + OMP can acquire its config lock and rewrite the file when persisting + runtime changes (`/settings`, onboarding). Those runtime changes are + overwritten by the declared values again on the next `home-manager switch`. ''; example = { @@ -38,8 +42,21 @@ in config = lib.mkIf cfg.enable { home.packages = [ cfg.package ]; - home.file.".omp/agent/config.yml" = lib.mkIf (cfg.settings != null) { - source = yaml.generate "omp-config.yml" cfg.settings; + + # OMP rewrites its config at runtime and acquires an advisory lock on it + # first; on macOS the lock backend creates an flock sidecar next to the + # target file. A `home.file` store symlink is read-only and lives under + # /nix/store, so both the lock and the atomic rewrite fail with EACCES and + # break every launch. Copy a writable regular file instead. The DAG entry + # is written literally (rather than via `lib.hm.dag.entryAfter`) so the + # home-manager-free module evaluation in `flake.nix` keeps working. + home.activation.ompConfig = lib.mkIf (cfg.settings != null) { + before = [ ]; + after = [ "writeBoundary" ]; + data = '' + run mkdir -p "$HOME/.omp/agent" + run install -m 600 ${configFile} "$HOME/.omp/agent/config.yml" + ''; }; }; } diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 4901d84f7..386c86927 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Fixed the Home Manager module (`programs.omp.settings`) breaking every launch on macOS with `Failed to acquire native file lock … Permission denied (os error 13)`. The declared config is now copied into `~/.omp/agent/config.yml` as a writable file via `home.activation` instead of a read-only `/nix/store` symlink, so OMP can acquire its config lock and persist runtime changes; `home-manager switch` still reapplies the declared settings ([#8775](https://github.com/can1357/oh-my-pi/issues/8775)). + ## [17.3.5] - 2026-08-16 ### Added