pi-goal-list-loop-audit 0.29.2 → 0.29.4

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.
@@ -1602,6 +1602,12 @@ async function showDecisionPrompt(ctx: ExtensionContext): Promise<boolean> {
1602
1602
  if (!pick) return true; // Escape — the widget card remains the fallback
1603
1603
  const idx = options.indexOf(pick);
1604
1604
  const label = g.pauseOptions![idx] ?? pick.replace(/ {2}\(recommended\)$/, "");
1605
+ // v0.29.3: the wipe escape — "… (/glla wipe)" options run the wipe
1606
+ // (which Confirms on its own — destructive actions keep their gate).
1607
+ if (/\(\/glla wipe\)\s*$/.test(label)) {
1608
+ await cmdGllaWipe(ctx);
1609
+ return true;
1610
+ }
1605
1611
  // Executable options — "Label (/goal cancel)" — RUN the command.
1606
1612
  // Placeholder commands (…/<arg>) fall through to the message path.
1607
1613
  const cmdMatch = label.match(/\(\/(goal|list|loop) ([a-z]+)\)\s*$/);
@@ -3377,13 +3383,11 @@ function registerAgentTools(pi: any, ctx: ExtensionContext): void {
3377
3383
  persistState(liveCtx);
3378
3384
  appendLedger(liveCtx.cwd, "list_added", { id: item.id, objective: item.objective, drafted: true });
3379
3385
  if (!state.goal || state.goal.status === "complete" || state.goal.status === "aborted") {
3380
- // v0.28.28: an AUTO-ACCEPTED draft does not auto-start unless
3381
- // autoResume is on accepting a draft is not consent to start.
3382
- if (autoAccept && loadSettings(liveCtx.cwd).autoResume !== true) {
3383
- liveCtx.ui.notify(`Auto-accepted and QUEUED (autoResume off — not auto-started): ${extracted.objective.slice(0, 80)} /list next when ready.`, "info");
3384
- appendLedger(liveCtx.cwd, "list_autoactivation_held", { source: "draft-autoaccepted", count: 1 });
3385
- return { content: [{ type: "text", text: "Draft accepted and added to the list, but NOT started (the user's autoResume setting is off — auto-accepted drafts queue, they don't auto-start). Do NOT begin work. Tell the user: /list next starts it." }], details: {} };
3386
- }
3386
+ // v0.29.4: an auto-accepted draft STARTS autoAcceptDrafts is the
3387
+ // pre-consent (the user asked for the draft in-session). The
3388
+ // 0.28.28 autoResume hold is lifted: that setting now gates ONLY
3389
+ // launch-time restore. The 0.29.1 zombie-twin guard already
3390
+ // refused duplicates of just-completed work upstream.
3387
3391
  activateNextListItem(liveCtx);
3388
3392
  return { content: [{ type: "text", text: "Confirmed and activated (list was empty). Begin work now." }], details: {} };
3389
3393
  }
@@ -3391,20 +3395,11 @@ function registerAgentTools(pi: any, ctx: ExtensionContext): void {
3391
3395
  }
3392
3396
  const goal = createGoal(full, liveCtx);
3393
3397
  setGoal(goal, liveCtx, autoAccept ? "draft-autoaccepted" : "draft-confirmed");
3394
- // v0.28.28: auto-accepted goal drafts are created HELD when autoResume
3395
- // is off auto-accept delegates the Confirm click, not the decision
3396
- // to start. Explicit user-confirmed drafts still start immediately.
3397
- if (autoAccept && loadSettings(liveCtx.cwd).autoResume !== true) {
3398
- updateGoal({
3399
- status: "paused",
3400
- pauseKind: "blocked",
3401
- pauseReason: "auto-accepted draft — held for the user's go-ahead (autoResume off)",
3402
- pauseSuggestedAction: "/goal resume to start · /goal cancel to drop · /glla autoresume=on starts auto-accepted drafts automatically",
3403
- }, liveCtx);
3404
- appendLedger(liveCtx.cwd, "draft_held", { goalId: goal.id, reason: "autoaccept-autoresume-off" });
3405
- liveCtx.ui.notify(`Draft auto-accepted and HELD (autoResume off): ${goal.objective.slice(0, 80)} — /goal resume to start, /goal cancel to drop.`, "info");
3406
- return { content: [{ type: "text", text: "Goal accepted but HELD (the user's autoResume setting is off — auto-accepted drafts do not auto-start). Do NOT begin work. Tell the user: /goal resume starts it, /goal cancel drops it." }], details: {} };
3407
- }
3398
+ // v0.29.4: auto-accepted drafts START (autoAcceptDrafts is the
3399
+ // pre-consent — the user asked for the draft in-session). autoResume
3400
+ // no longer gates draft starts; it gates ONLY launch-time restore of
3401
+ // persisted state ("load it but not auto start it"). Zombie twins of
3402
+ // just-completed work are refused upstream (0.29.1).
3408
3403
  iterationCounter = 0;
3409
3404
  consecutiveErrorIterations = 0;
3410
3405
  consecutiveAbortIterations = 0;
@@ -5031,7 +5026,10 @@ export default function (pi: ExtensionAPI): void {
5031
5026
  if (next.length !== before) changed = true;
5032
5027
  }
5033
5028
  if (changed) pi.setActiveTools(next);
5034
- if (!toolHealNotified) {
5029
+ if (!toolHealNotified && missing.length > 0) {
5030
+ // v0.29.3: the notify used to fire even when NOTHING was missing —
5031
+ // "glla: 0 agent tool(s) were hidden … re-activated ()" at every pi
5032
+ // start (field-observed in darklord). Warn only on a real heal.
5035
5033
  toolHealNotified = true;
5036
5034
  const list = missing.join(", ");
5037
5035
  ctx.ui.notify(
@@ -5276,7 +5274,12 @@ export default function (pi: ExtensionAPI): void {
5276
5274
  updateGoal({
5277
5275
  status: "paused",
5278
5276
  pauseKind: "decision",
5279
- pauseOptions: ["Stop the loop, then resume the goal (/loop stop)", "Cancel the goal (/goal cancel) — the loop keeps running"],
5277
+ // v0.29.3: third option the wipe escape. Old projects stack a
5278
+ // goal AND a loop AND a list from pre-guard versions; arbitrating
5279
+ // between two artifacts the user doesn't even remember is the odd
5280
+ // part — "i feel like wipe does [make sense]". Wipe keeps its own
5281
+ // Confirm (destructive), so picking it is safe to offer.
5282
+ pauseOptions: ["Stop the loop, then resume the goal (/loop stop)", "Cancel the goal (/goal cancel) — the loop keeps running", "Wipe everything — clean slate for stale leftovers (/glla wipe)"],
5280
5283
  pauseRecommended: 1,
5281
5284
  pauseReason: "held on session load — the loop owns the active slot (one active thing at a time)",
5282
5285
  pauseSuggestedAction: "/loop to work the loop, or /loop stop then /goal resume to work the goal",
@@ -5353,6 +5356,12 @@ export default function (pi: ExtensionAPI): void {
5353
5356
  // "unproductive turns" pause). pi's own retry owns the backoff;
5354
5357
  // the nudge counter neither increments nor resets on these turns.
5355
5358
  appendLedger(ctx.cwd, "stall_nudge_exempt_error", { nudgesSoFar: heartbeatNudges });
5359
+ } else if (lastA?.stopReason === "aborted") {
5360
+ // v0.29.4: user aborts are not model unproductivity either — the
5361
+ // user pressed Esc. Counting the interrupt tripped the stall brake
5362
+ // on the USER's action (pully field case: Esc-spam → STALL WARNING
5363
+ // 1/3, 2/3 → a bogus "stalled" pause). Neither increment nor reset.
5364
+ appendLedger(ctx.cwd, "stall_nudge_exempt_aborted", { nudgesSoFar: heartbeatNudges });
5356
5365
  } else {
5357
5366
  const s = loadSettings(ctx.cwd);
5358
5367
  const shortWordsThr = s.stallShortWords ?? DEFAULT_STALL_SHORT_WORDS;
@@ -5515,6 +5524,13 @@ export default function (pi: ExtensionAPI): void {
5515
5524
  appendLedger(ctx.cwd, "goal_paused", { reason: "5 consecutive aborts (user interrupted)" });
5516
5525
  return;
5517
5526
  }
5527
+ // v0.29.4: an abort stands the chain DOWN — no auto re-fire. The old
5528
+ // fall-through re-fired the continuation immediately, so every Esc
5529
+ // was answered by another turn under the user's hands ("it auto
5530
+ // triggered and I kept spamming esc on it" — pully, 2026-07-30).
5531
+ ctx.ui.notify(`${goalNoun()} standing down — turn aborted by user (not counted toward stalls). /goal resume to continue, /goal cancel to stop.`, "info");
5532
+ appendLedger(ctx.cwd, "abort_stand_down", { consecutiveAborts: consecutiveAbortIterations });
5533
+ return;
5518
5534
  } else {
5519
5535
  consecutiveErrorIterations = 0;
5520
5536
  consecutiveAbortIterations = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-goal-list-loop-audit",
3
- "version": "0.29.2",
3
+ "version": "0.29.4",
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",