git-sync: sync ~/.codex history repo across machines

Mirror the claude-history setup for Codex: ~/.codex is now a git repo
(github.com/colonelpanic8/codex-history) holding session rollouts and
history.jsonl from all machines, synced by git-sync-rs in watch mode.

- Generalize the nixos host gate (claudeHistoryHosts -> aiHistoryHosts)
  and add codex-history alongside claude-history on both NixOS and darwin.
- Drop the old HM-managed dotfiles/codex/.gitignore; the repo ships its
  own real .gitignore (git won't read a symlinked one).
- Shield dotfiles/codex/* in the root .gitignore so nested codex history
  can't be committed into dotfiles on darwin (where ~/.codex resolves
  into dotfiles/codex).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-11 01:45:40 -07:00
parent 994291b969
commit f3649945cb
4 changed files with 31 additions and 15 deletions

8
.gitignore vendored
View File

@@ -61,3 +61,11 @@ gotools
!/dotfiles/claude/settings.json
!/dotfiles/claude/settings.local.json
!/dotfiles/claude/settings.local.json.example
# Same story for Codex: ~/.codex resolves into dotfiles/codex on nix-darwin,
# so the codex-history repo and live Codex state nest inside this worktree.
# Allowlist only the HM-managed config.
/dotfiles/codex/*
!/dotfiles/codex/AGENTS.md
!/dotfiles/codex/config.toml
!/dotfiles/codex/skills

View File

@@ -1,8 +0,0 @@
*
!.gitignore
!AGENTS.md
!config.toml
!skills
# Legacy generated/local Codex state under this repo stays ignored. Active
# host-local Codex fragments now live under ~/.codex.

View File

@@ -11,6 +11,7 @@
orgPath = "${config.home.homeDirectory}/org";
passwordStorePath = "${config.home.homeDirectory}/.password-store";
claudePath = "${config.home.homeDirectory}/.claude";
codexPath = "${config.home.homeDirectory}/.codex";
in {
services.git-sync = {
enable = true;
@@ -30,6 +31,11 @@ in {
uri = "git@github.com:colonelpanic8/claude-history.git";
interval = 600;
};
codex-history = {
path = codexPath;
uri = "git@github.com:colonelpanic8/codex-history.git";
interval = 600;
};
};
};
@@ -43,5 +49,7 @@ in {
# untracked session files and throttle event-driven syncs.
git-sync-claude-history.config.ProgramArguments =
lib.mkForce ["${gitSyncPackage}/bin/git-sync-rs" "-d" claudePath "watch" "--new-files" "true" "--min-interval" "300"];
git-sync-codex-history.config.ProgramArguments =
lib.mkForce ["${gitSyncPackage}/bin/git-sync-rs" "-d" codexPath "watch" "--new-files" "true" "--min-interval" "300"];
};
}

View File

@@ -5,11 +5,11 @@
...
}: let
gitSyncServicePath = lib.makeBinPath [pkgs.coreutils pkgs.git pkgs.openssh];
# ~/.claude history sync is being rolled out machine-by-machine; each new
# machine needs its existing history merged into the repo first (see
# github.com/colonelpanic8/claude-history).
claudeHistoryHosts = ["ryzen-shine" "railbird-sf" "jay-lenovo" "strixi-minaj"];
syncClaudeHistory = builtins.elem config.networking.hostName claudeHistoryHosts;
# AI chat-history sync (Claude Code + Codex) is rolled out machine-by-machine;
# each new machine needs its existing history merged into the repo first (see
# github.com/colonelpanic8/claude-history and .../codex-history).
aiHistoryHosts = ["ryzen-shine" "railbird-sf" "jay-lenovo" "strixi-minaj"];
syncAiHistory = builtins.elem config.networking.hostName aiHistoryHosts;
mkGitSyncTrayOverrides = icon: {
Service = {
Environment = lib.mkMerge [
@@ -40,12 +40,17 @@ in {
uri = "git@github.com:IvanMalison/.password-store.git";
};
}
// lib.optionalAttrs syncClaudeHistory {
// lib.optionalAttrs syncAiHistory {
claude-history = {
path = config.home.homeDirectory + "/.claude";
uri = "git@github.com:colonelpanic8/claude-history.git";
interval = 600;
};
codex-history = {
path = config.home.homeDirectory + "/.codex";
uri = "git@github.com:colonelpanic8/codex-history.git";
interval = 600;
};
};
};
@@ -55,13 +60,16 @@ in {
lib.nameValuePair "git-sync-${name}"
(mkGitSyncTrayOverrides (repoIcons.${name} or "git")))
config.services.git-sync.repositories)
(lib.optionalAttrs syncClaudeHistory {
(lib.optionalAttrs syncAiHistory {
# Live sessions append to their transcript on every message; sync
# untracked session files and throttle event-driven syncs so an
# active session doesn't push once per append.
git-sync-claude-history.Service.ExecStart =
lib.mkForce
"${pkgs.git-sync-rs}/bin/git-sync-rs watch --new-files true --min-interval 300";
git-sync-codex-history.Service.ExecStart =
lib.mkForce
"${pkgs.git-sync-rs}/bin/git-sync-rs watch --new-files true --min-interval 300";
})
];
};