@tekmidian/pai 0.32.2 → 0.32.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/hooks/session-stop.sh +47 -9
package/package.json
CHANGED
|
@@ -88,16 +88,54 @@ fi
|
|
|
88
88
|
"$PAI_OS" session slug "$PROJECT_SLUG" latest --apply 2>/dev/null || true
|
|
89
89
|
|
|
90
90
|
# ---------------------------------------------------------------------------
|
|
91
|
-
#
|
|
91
|
+
# Periodic housekeeping — NOT every turn
|
|
92
92
|
# ---------------------------------------------------------------------------
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
#
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
|
|
100
|
-
|
|
93
|
+
# The `Stop` event does not mean "the session ended". Claude Code fires it at the
|
|
94
|
+
# end of EVERY assistant turn, so everything in this file runs after every single
|
|
95
|
+
# message. Measured 2026-08-04, on this machine:
|
|
96
|
+
#
|
|
97
|
+
# session cleanup --execute 17705 ms <- machine-wide sweep
|
|
98
|
+
# obsidian sync 2813 ms <- walks the vault
|
|
99
|
+
# detect + slug + checkpoint + handover ~300 ms total
|
|
100
|
+
# stop-hook.mjs (separate hook) 4324 ms
|
|
101
|
+
#
|
|
102
|
+
# So roughly 25 SECONDS of work between one message and the next, and Matthias
|
|
103
|
+
# could see it: "in the middle of the session I keep seeing running stop hooks".
|
|
104
|
+
# Two of those calls are whole-machine passes over 112 project directories and
|
|
105
|
+
# ~2900 transcripts. Doing that per turn is not a slow implementation, it is the
|
|
106
|
+
# wrong trigger.
|
|
107
|
+
#
|
|
108
|
+
# The cheap calls stay per-turn: a checkpoint and a handover after every turn are
|
|
109
|
+
# genuine crash insurance, and together they cost under a fifth of a second.
|
|
110
|
+
#
|
|
111
|
+
# The expensive two are debounced rather than moved to SessionEnd, deliberately —
|
|
112
|
+
# SessionEnd does not fire when a session is killed, and these are exactly the
|
|
113
|
+
# jobs that matter after an unclean exit. A stamp file gets them run regularly
|
|
114
|
+
# without paying for them every turn. Override with PAI_HOUSEKEEPING_INTERVAL
|
|
115
|
+
# (seconds, 0 disables the debounce and restores per-turn behaviour).
|
|
116
|
+
|
|
117
|
+
HOUSEKEEP_INTERVAL="${PAI_HOUSEKEEPING_INTERVAL:-1800}"
|
|
118
|
+
HOUSEKEEP_STAMP="$HOME/.config/pai/.last-housekeeping"
|
|
119
|
+
mkdir -p "$(dirname "$HOUSEKEEP_STAMP")" 2>/dev/null || true
|
|
120
|
+
|
|
121
|
+
housekeeping_due() {
|
|
122
|
+
[ "$HOUSEKEEP_INTERVAL" = "0" ] && return 0
|
|
123
|
+
[ -f "$HOUSEKEEP_STAMP" ] || return 0
|
|
124
|
+
local last now
|
|
125
|
+
last=$(cat "$HOUSEKEEP_STAMP" 2>/dev/null || echo 0)
|
|
126
|
+
case "$last" in ''|*[!0-9]*) last=0 ;; esac
|
|
127
|
+
now=$(date +%s)
|
|
128
|
+
[ $((now - last)) -ge "$HOUSEKEEP_INTERVAL" ]
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if housekeeping_due; then
|
|
132
|
+
# Stamp BEFORE running, not after: these take ~20s, and two turns finishing
|
|
133
|
+
# close together would otherwise both pass the check and run concurrently.
|
|
134
|
+
date +%s > "$HOUSEKEEP_STAMP" 2>/dev/null || true
|
|
135
|
+
|
|
136
|
+
"$PAI_OS" obsidian sync 2>/dev/null || true
|
|
137
|
+
"$PAI_OS" session cleanup --execute 2>/dev/null || true
|
|
138
|
+
fi
|
|
101
139
|
|
|
102
140
|
# ---------------------------------------------------------------------------
|
|
103
141
|
# Auto-checkpoint before stop (captures final state)
|