diff --git a/contrib/README.md b/contrib/README.md index f8ca0b9..283c029 100644 --- a/contrib/README.md +++ b/contrib/README.md @@ -1,11 +1,26 @@ -# contrib/ — automation recipes for `mempalace-session` +# contrib/ — automation recipes for `mempalace-session` and `mempalace-pi-session` -Manual invocation of `mempalace-session` is fine on a machine you actively drive. For long-running devboxes, a weekly automated mine keeps the palace fresh without thinking about it. This directory ships ready-to-use templates for two common scheduling mechanisms. +Manual invocation of the session-mining wrappers is fine on a machine you actively drive. For long-running devboxes, a weekly automated mine keeps the palace fresh without thinking about it. This directory ships ready-to-use templates for two common scheduling mechanisms, for each wrapper. > **Before using either**: confirm the toolkit is installed and the wrapper works — -> `mempalace-session --dry-run` should list qualifying sessions. If that errors, fix the install before scheduling. +> `mempalace-session --dry-run` (and/or `mempalace-pi-session --dry-run`) should list qualifying sessions. If that errors, fix the install before scheduling. -Pick **one**. Running both would double-mine (harmless — dedup skips everything on the second run — but wastes wall time on the HNSW repair). +Pick **one scheduler** (systemd *or* launchd *or* cron). The opencode and pi jobs can be installed side by side and staggered — templates ship with Mon 03:00 for opencode, Tue 03:00 for pi to avoid racing the post-mine HNSW repair. + +## Templates at a glance + +| File | What it schedules | When | +|---|---|---| +| `systemd/mempalace-session.{service,timer}` | opencode → palace | Mon 03:00 | +| `systemd/mempalace-pi-session.{service,timer}` | pi → palace | Tue 03:00 | +| `systemd/mempalace-session-devbox.{service,timer}` | opencode (inside a devbox container) → palace | Mon 03:00 | +| `launchd/se.jordbo.mempalace-session.plist` | opencode → palace (macOS) | Mon 03:00 | +| `launchd/se.jordbo.mempalace-pi-session.plist` | pi → palace (macOS) | Tue 03:00 | +| `cron/mempalace-session.cron` | opencode → palace | Mon 03:00 | +| `cron/mempalace-pi-session.cron` | pi → palace | Tue 03:00 | +| `cron/mempalace-session-devbox.cron` | opencode (devbox) → palace | Mon 03:00 | + +The pi variants are drop-in copies of the opencode variants with script name and schedule updated; the install recipes below apply equally — just swap `mempalace-session` for `mempalace-pi-session` and the schedule day. --- diff --git a/contrib/cron/mempalace-pi-session.cron b/contrib/cron/mempalace-pi-session.cron new file mode 100644 index 0000000..3f42495 --- /dev/null +++ b/contrib/cron/mempalace-pi-session.cron @@ -0,0 +1,18 @@ +# Sample crontab entry for mempalace-pi-session. +# +# Runs a full pi → MemPalace mine weekly (Tuesdays at 03:00 local). +# Staggered from mempalace-session.cron (Mondays) so if both are installed +# they don't race the post-mine HNSW repair step. +# +# To install: +# (crontab -l 2>/dev/null; cat contrib/cron/mempalace-pi-session.cron) | crontab - +# +# To remove, edit your crontab: +# crontab -e +# +# Replace USER with your actual username. + +PATH=/home/USER/.local/bin:/usr/local/bin:/usr/bin:/bin + +# m h dom mon dow command +0 3 * * 2 mempalace-pi-session >> /home/USER/.cache/mempalace-pi-session/cron.log 2>&1 diff --git a/contrib/launchd/se.jordbo.mempalace-pi-session.plist b/contrib/launchd/se.jordbo.mempalace-pi-session.plist new file mode 100644 index 0000000..f856d7c --- /dev/null +++ b/contrib/launchd/se.jordbo.mempalace-pi-session.plist @@ -0,0 +1,77 @@ + + + + + + + Label + se.jordbo.mempalace-pi-session + + ProgramArguments + + /Users/USER/.local/bin/mempalace-pi-session + + + + EnvironmentVariables + + PATH + /Users/USER/.local/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin + HOME + /Users/USER + + + + StartCalendarInterval + + Weekday + 2 + Hour + 3 + Minute + 0 + + + RunAtLoad + + + ProcessType + Background + LowPriorityIO + + Nice + 10 + + + ExitTimeOut + 7200 + + + StandardOutPath + /Users/USER/Library/Logs/mempalace-pi-session.log + StandardErrorPath + /Users/USER/Library/Logs/mempalace-pi-session.err.log + + diff --git a/contrib/systemd/mempalace-pi-session.service b/contrib/systemd/mempalace-pi-session.service new file mode 100644 index 0000000..286ebb8 --- /dev/null +++ b/contrib/systemd/mempalace-pi-session.service @@ -0,0 +1,23 @@ +[Unit] +Description=Mine pi coding-agent session history into MemPalace +Documentation=https://gitea.jordbo.se/joakimp/mempalace-toolkit +# Only run if pi has actually been used (avoids noise on idle machines) +ConditionPathExists=%h/.pi/agent/sessions +# Don't start if a previous run is still going +ConditionPathExists=!%t/mempalace-pi-session.lock + +[Service] +Type=oneshot +# The wrapper writes to ~/.cache/mempalace-pi-session/ and the palace. +# Keep stdout/stderr in the journal — inspect with: +# journalctl --user -u mempalace-pi-session --since today +ExecStart=%h/.local/bin/mempalace-pi-session +# Belt-and-braces lock so two overlapping runs can't corrupt staging +ExecStartPre=/bin/sh -c 'touch %t/mempalace-pi-session.lock' +ExecStopPost=/bin/sh -c 'rm -f %t/mempalace-pi-session.lock' +# Protect against runaway runs. Pi sessions tend to be short/tactical so the +# corpus is much smaller than opencode's; 2h is generous headroom. +TimeoutStartSec=7200 +# Low priority — this is background maintenance +Nice=10 +IOSchedulingClass=idle diff --git a/contrib/systemd/mempalace-pi-session.timer b/contrib/systemd/mempalace-pi-session.timer new file mode 100644 index 0000000..95f5a11 --- /dev/null +++ b/contrib/systemd/mempalace-pi-session.timer @@ -0,0 +1,18 @@ +[Unit] +Description=Weekly pi → MemPalace session mine +Documentation=https://gitea.jordbo.se/joakimp/mempalace-toolkit + +[Timer] +# Every Tuesday at 03:00 local time. Staggered from mempalace-session.timer +# (Mon 03:00) so if both are installed, the HNSW repair step in one doesn't +# race the repair step in the other. +# Use `systemctl --user list-timers mempalace-pi-session.timer` to see next run. +OnCalendar=Tue 03:00 +# If the machine was off at the scheduled time, run at next boot. +Persistent=true +# Randomize up to 30 minutes to avoid thundering-herd across machines. +RandomizedDelaySec=30m +AccuracySec=1m + +[Install] +WantedBy=timers.target