From 1b0f3ef4a544ed9bf0f05a132a4712fbcad8a60f Mon Sep 17 00:00:00 2001 From: Colin Powell Date: Thu, 17 Sep 2026 11:35:19 -0400 Subject: [PATCH] [systemd] Restore claude-save timer and make targets The claude and claude-save Makefile targets and both unit files were dropped when master was rewound upstream, leaving only the enable symlink in timers.target.wants pointing at a missing unit. The timer kept firing every 30 minutes and failing with "No rule to make target 'claude-save'", so session state stopped syncing. Co-Authored-By: Claude Opus 5 (1M context) --- Makefile | 43 ++++++++++++++++++- .../.config/systemd/user/claude-save.service | 7 +++ .../.config/systemd/user/claude-save.timer | 11 +++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 systemd/.config/systemd/user/claude-save.service create mode 100644 systemd/.config/systemd/user/claude-save.timer diff --git a/Makefile b/Makefile index 237c25d..45a3c98 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,13 @@ -.PHONY: os stow deps +.PHONY: all os stow deps claude claude-save OS_NAME := $(shell uname -s | tr A-Z a-z) +CLAUDE_HISTORY_REPO := git@git.service:secstate/claude-history +CLAUDE_HISTORY_DIR := $(HOME)/.claude-history +CLAUDE_HISTORY_PATHS := projects plans tasks history.jsonl + +all: stow claude + stow: mkdir -p ~/.gnupg && chmod 0700 ~/.gnupg stow -t ~ */ @@ -18,3 +24,38 @@ deps: os: @echo $(OS_NAME) + +# Clone the private session-state repo and symlink it into ~/.claude so Claude +# Code resumes prior sessions. Sessions only match when the checkout path is +# identical to the one recorded in the project directory name. +claude: + @test -d $(CLAUDE_HISTORY_DIR) || git clone $(CLAUDE_HISTORY_REPO) $(CLAUDE_HISTORY_DIR) + @mkdir -p ~/.claude + @for p in $(CLAUDE_HISTORY_PATHS); do \ + test -e $(CLAUDE_HISTORY_DIR)/$$p || continue; \ + test -L ~/.claude/$$p && continue; \ + if [ -e ~/.claude/$$p ]; then \ + echo "claude: ~/.claude/$$p exists and is not a symlink, leaving it alone"; \ + continue; \ + fi; \ + ln -s $(CLAUDE_HISTORY_DIR)/$$p ~/.claude/$$p; \ + echo "claude: linked $$p"; \ + done + @if [ $(OS_NAME) = "linux" ]; then \ + systemctl --user daemon-reload && \ + systemctl --user enable --now claude-save.timer; \ + fi + +claude-save: + @cd $(CLAUDE_HISTORY_DIR) && \ + git add -A && \ + if git diff --cached --quiet; then \ + echo "claude-save: nothing to commit"; \ + else \ + git commit -qm "Sync session state" && echo "claude-save: committed"; \ + fi && \ + if git remote get-url origin >/dev/null 2>&1; then \ + git push -q && echo "claude-save: pushed"; \ + else \ + echo "claude-save: no origin remote, skipping push"; \ + fi diff --git a/systemd/.config/systemd/user/claude-save.service b/systemd/.config/systemd/user/claude-save.service new file mode 100644 index 0000000..4872d72 --- /dev/null +++ b/systemd/.config/systemd/user/claude-save.service @@ -0,0 +1,7 @@ +[Unit] +Description="Commit and push Claude Code session state" +Requires=claude-save.timer + +[Service] +Type=oneshot +ExecStart=/usr/bin/make -C %h/.dotfiles claude-save diff --git a/systemd/.config/systemd/user/claude-save.timer b/systemd/.config/systemd/user/claude-save.timer new file mode 100644 index 0000000..ddcd79b --- /dev/null +++ b/systemd/.config/systemd/user/claude-save.timer @@ -0,0 +1,11 @@ +[Unit] +Description="Timer for saving Claude Code session state" + +[Timer] +Unit=claude-save.service +OnBootSec=5m +OnCalendar=*:0/30 +Persistent=true + +[Install] +WantedBy=timers.target