pi-goal-list-loop-audit 0.29.12 → 0.29.13

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.
@@ -58,6 +58,11 @@ export interface Settings {
58
58
  /** Consecutive stuck interventions before a loop stops (default 5,
59
59
  * 10 under aggressiveMode). */
60
60
  stuckMaxInterventions?: number;
61
+ /** v0.29.13: on a stale-handle terminal, inject /reload into our own
62
+ * tmux pane (keystroke self-heal; pi walls ctx.reload() behind
63
+ * assertActive). Default true; only acts when TMUX and TMUX_PANE are
64
+ * set — pi outside tmux just gets the manual warning. */
65
+ autoReloadOnStale?: boolean;
61
66
  /** v0.26.1: consecutive heartbeat refires without a real turn before
62
67
  * the goal pauses / loop stops (default 5; 0 = never escalate). */
63
68
  stallEscalationRefires?: number;
@@ -186,6 +191,7 @@ export const SETTINGS_KEYS: Array<keyof Settings> = [
186
191
  "quotaRetryMinutes",
187
192
  "stuckMaxInterventions",
188
193
  "stallEscalationRefires",
194
+ "autoReloadOnStale",
189
195
  "stallShortWords",
190
196
  "stallSimilarityThreshold",
191
197
  "postaudit",
@@ -15,6 +15,7 @@
15
15
  */
16
16
 
17
17
  import * as fs from "node:fs";
18
+ import { exec } from "node:child_process";
18
19
  import * as os from "node:os";
19
20
  import * as path from "node:path";
20
21
 
@@ -229,6 +230,29 @@ function goStaleTerminal(ctx: ExtensionContext, where: string): void {
229
230
  }
230
231
  ctx.ui.notify(`glla: ${guidance}`, "warning");
231
232
  notifyExternal(ctx, `glla: extension api stale — restart pi. (${where})`);
233
+ attemptTmuxAutoReload(ctx, where);
234
+ }
235
+
236
+ /** v0.29.13: automatic recovery — the zombie handle can't call ctx.reload()
237
+ * (pi walls EVERY runtime method behind assertActive), but fs/child_process
238
+ * are extension-side and still work. When pi runs inside tmux (this rig's
239
+ * shape), inject /reload as keystrokes into our own pane: pi rebuilds the
240
+ * extension runtime in place, the fresh instance loads .pi-glla state and
241
+ * holds (autoresume=on resumes for you). Opt out: autoReloadOnStale=false.
242
+ * Best-effort: the manual warning already fired, so failures cost nothing. */
243
+ function attemptTmuxAutoReload(ctx: ExtensionContext, where: string): void {
244
+ try {
245
+ if (loadSettings(ctx.cwd).autoReloadOnStale === false) return;
246
+ const pane = process.env.TMUX_PANE;
247
+ if (!process.env.TMUX || !pane || !/^%\d+$/.test(pane)) return;
248
+ appendLedger(ctx.cwd, "auto_reload_injected", { where, pane });
249
+ ctx.ui.notify("glla: injecting /reload into this pane via tmux — extensions rebuild in place and the fresh instance holds state. /glla resume after (automatic with autoresume=on).", "info");
250
+ // Escape dismisses any overlay; the dead session sits at an empty prompt.
251
+ const cmd = `tmux send-keys -t ${pane} Escape && sleep 0.3 && tmux send-keys -t ${pane} -l '/reload' && tmux send-keys -t ${pane} Enter`;
252
+ exec(cmd, () => { /* best-effort */ });
253
+ } catch {
254
+ /* never let recovery take the warning path down */
255
+ }
232
256
  }
233
257
 
234
258
  /** TEST-ONLY hook (tests/harness): the stale flag is process-terminal in
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-goal-list-loop-audit",
3
- "version": "0.29.12",
3
+ "version": "0.29.13",
4
4
  "description": "Goal. Loop. Audit. Done. \u2014 a pi-coding-agent extension that supervises long-running work, with isolated auditor on each completion. Beat bamboozling by design: the auditor runs in a fresh session with no extensions, no skills, no editor \u2014 only the read tools needed to verify your goal.",
5
5
  "license": "MIT",
6
6
  "author": "dracon",