@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tekmidian/pai",
3
- "version": "0.32.2",
3
+ "version": "0.32.3",
4
4
  "description": "PAI Knowledge OS — Personal AI Infrastructure with federated memory and project management",
5
5
  "type": "module",
6
6
  "main": "dist/index.mjs",
@@ -88,16 +88,54 @@ fi
88
88
  "$PAI_OS" session slug "$PROJECT_SLUG" latest --apply 2>/dev/null || true
89
89
 
90
90
  # ---------------------------------------------------------------------------
91
- # Sync Obsidian vault
91
+ # Periodic housekeeping — NOT every turn
92
92
  # ---------------------------------------------------------------------------
93
-
94
- "$PAI_OS" obsidian sync 2>/dev/null || true
95
-
96
- # ---------------------------------------------------------------------------
97
- # Clean up empty/stale session notes
98
- # ---------------------------------------------------------------------------
99
-
100
- "$PAI_OS" session cleanup --execute 2>/dev/null || true
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)