pi-goal-list-loop-audit 0.28.33 → 0.28.34

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/README.md CHANGED
@@ -201,7 +201,7 @@ No external watchdog plugin needed.
201
201
  /glla # open the settings UI
202
202
  /glla model=provider/id # auditor model override → GLOBAL
203
203
  /glla thinking=high # auditor thinking → GLOBAL
204
- /glla notify='cmd "$1"' # push on complete/pause/stop → GLOBAL
204
+ /glla notify='cmd "$1"' # custom push cmd · unset = auto-detect (notify-send/osascript) · off = silent → GLOBAL
205
205
  /glla tokenlimit=10000000 # per-goal token budget (default: off) → GLOBAL
206
206
  /glla tokenlimit=0 # explicitly no cap (the default)
207
207
  /glla wedgealert=30 # hung-command alert minutes (default: 30, 0 = off)
@@ -233,15 +233,14 @@ activates the moment the agent proposes it, with a notification and a
233
233
  `draft_autoaccepted` ledger entry (auto-accept is never silent). The seed
234
234
  carries the intent. Pair with `autoresume=on` for fully unattended rigs.
235
235
 
236
- ## Subagents (`@tintinweb/pi-subagents`)
236
+ ## Subagents
237
237
 
238
- Subagent sessions bind extensions too, so glla loads there — by design the
239
- **main session owns the goal/loop/list; subagents are workers** (v0.23.8):
238
+ glla's guarantees here come from glla itself (session-handle
239
+ discrimination), not from any specific subagent plugin — any Agent-tool
240
+ provider gets them. Subagent sessions bind extensions too, so glla loads
241
+ there — by design the **main session owns the goal/loop/list; subagents
242
+ are workers** (v0.23.8):
240
243
 
241
- - Read-only agents (Explore, Plan) get no glla tools (pi-subagents gates
242
- them); general-purpose agents see them but state-mutating calls
243
- (`complete_goal`, `propose_*`, `list_add`, `pause_goal`, …) are refused
244
- with "report back to the main agent".
245
244
  - A subagent session never clobbers the loop's session handle, never runs
246
245
  the restore gate, and never drives continuation — so the heartbeat,
247
246
  wedge alert, and auto-resume machinery always act on the main session.
@@ -249,6 +248,11 @@ Subagent sessions bind extensions too, so glla loads there — by design the
249
248
  is the discriminator.)
250
249
  - Subagent tool activity counts as activity for the wedge clock — a long
251
250
  subagent run is work, not a hang.
251
+ - With `@tintinweb/pi-subagents` specifically (the one we test against):
252
+ read-only agents (Explore, Plan) get no glla tools; general-purpose
253
+ agents see them but state-mutating calls (`complete_goal`, `propose_*`,
254
+ `list_add`, `pause_goal`, …) are refused with "report back to the main
255
+ agent".
252
256
 
253
257
  ## Token guard
254
258
 
@@ -287,17 +291,25 @@ contradictory turns. One driver at a time:
287
291
  fine to keep, never run a ralph loop while a goal/list/loop is active.
288
292
 
289
293
  **Goes well with it**: `@juicesharp/rpiv-ask-user-question` (drafting uses its
290
- structured forms), `@tintinweb/pi-subagents` (spawn research/review subagents
291
- inside goal work), `@tintinweb/pi-tasks` (session-wide DAGs vs our goal-scoped
292
- task lists — different granularity), `pi-chrome` (the research/search path for
293
- goals — logged-in browsing with no extra services; standalone search skills
294
- like `mmx-cli`/`pi-search-skill` are optional conveniences for bulk queries,
295
- not requirements).
294
+ structured forms), any subagent provider — e.g. `@tintinweb/pi-subagents` —
295
+ (spawn research/review subagents inside goal work), `pi-chrome` (the
296
+ research/search path for goals — logged-in browsing with no extra services;
297
+ standalone search skills like `mmx-cli`/`pi-search-skill` are optional
298
+ conveniences for bulk queries, not requirements).
299
+
300
+ **Overlaps — pick one**: `@tintinweb/pi-tasks` is a second task list next to
301
+ `/list`, and in practice the glla list *is* the task list (queue, statuses,
302
+ per-item audit trail) while the todos end up the weaker copy. We ran both
303
+ and removed pi-tasks. If you truly need session-wide dependency DAGs beyond
304
+ one ordered queue, it exists — but installing both is not the ideal combo.
296
305
 
297
306
  **Two footnotes**: (1) extension-registered providers work in the main session
298
307
  but not the auditor's extension-less session — if audits fail auth, set the
299
- override once with `/glla model=`. (2) `pi-notify-agent` notifies on every turn;
300
- `/glla notify=` fires only on goal complete/pause/loop stop.
308
+ override once with `/glla model=`. (2) `pi-notify-agent` notifies on every
309
+ turn; glla pushes fire only where there is something to DO (pauses, verdicts,
310
+ storms, wedge) and work out of the box — with no `notify=` configured glla
311
+ auto-detects `notify-send`/`osascript`; `notify=off` silences, `notify='<cmd>'`
312
+ customizes.
301
313
 
302
314
  ## Files
303
315
 
@@ -1932,15 +1932,44 @@ function addSingleItem(ctx: ExtensionContext, raw: string): void {
1932
1932
  }
1933
1933
 
1934
1934
  /**
1935
- * Config-gated push notification: if settings.notifyCmd is set, shell out
1936
- * with the message as $1. Fire-and-forget — a broken notify command never
1937
- * blocks the loop. /glla notify='<cmd>' to configure.
1935
+ * Push notification, folded IN by default (v0.28.34 — user: "leaving it to
1936
+ * the user to set up sucks, cause then they won't have it"). Resolution:
1937
+ * notifyCmd === "off" → silent (explicit opt-out)
1938
+ * notifyCmd set → that command, message passed as $1
1939
+ * notifyCmd unset → auto-detect ONCE per session: notify-send
1940
+ * (Linux) or osascript (macOS); none → silent.
1941
+ * Pushes fire only where there is something to DO — pauses, auditor
1942
+ * verdicts, storms, wedge, persistence degradation — never per-turn noise.
1943
+ * Fire-and-forget: a broken notifier never blocks the loop.
1938
1944
  */
1945
+ let autoNotifyCmd: string | null | undefined; // undefined = not probed yet
1946
+
1947
+ function probeAutoNotify(ctx: ExtensionContext): void {
1948
+ if (autoNotifyCmd !== undefined || !extensionApi) return;
1949
+ autoNotifyCmd = null; // probing sentinel — drops at most the first push
1950
+ void extensionApi
1951
+ .exec("bash", ["-c", "command -v notify-send || command -v osascript || true"], { cwd: ctx.cwd })
1952
+ .then((r) => {
1953
+ const found = String((r as { stdout?: string }).stdout ?? "").trim();
1954
+ if (found.endsWith("notify-send")) autoNotifyCmd = `notify-send "pi-goal-list-loop-audit" "$1"`;
1955
+ // env-var handoff: the message never touches AppleScript quoting.
1956
+ else if (found.endsWith("osascript")) autoNotifyCmd = `GLLA_MSG="$1" osascript -e 'display notification (system attribute "GLLA_MSG") with title "pi-goal-list-loop-audit"'`;
1957
+ else autoNotifyCmd = null;
1958
+ })
1959
+ .catch(() => {
1960
+ autoNotifyCmd = null;
1961
+ });
1962
+ }
1963
+
1939
1964
  function notifyExternal(ctx: ExtensionContext, message: string): void {
1940
1965
  try {
1941
1966
  const settings = loadSettings(ctx.cwd);
1942
- const cmd = settings.notifyCmd;
1943
- if (!cmd || !extensionApi) return;
1967
+ if (settings.notifyCmd === "off" || !extensionApi) return;
1968
+ const cmd = settings.notifyCmd ?? autoNotifyCmd;
1969
+ if (!cmd) {
1970
+ if (settings.notifyCmd === undefined && autoNotifyCmd === undefined) probeAutoNotify(ctx);
1971
+ return;
1972
+ }
1944
1973
  void extensionApi.exec("bash", ["-c", cmd, "pi-goal-list-loop-audit", message], { cwd: ctx.cwd }).catch(() => {});
1945
1974
  } catch {
1946
1975
  // non-fatal by design
@@ -3892,7 +3921,7 @@ export async function handleSettingChoice(id: string, ctx: ExtensionContext): Pr
3892
3921
  // current effective subagent models. Treat as no-op.
3893
3922
  return;
3894
3923
  case "notifyCmd": {
3895
- const v = await ctx.ui.input("Notify command — the event message is passed as $1", "e.g. a desktop-notification or push command; empty = off");
3924
+ const v = await ctx.ui.input("Notify command — the event message is passed as $1", "custom command · empty = auto-detect (notify-send/osascript) · 'off' = silent");
3896
3925
  if (v !== undefined) saveSettings("global", ctx.cwd, { notifyCmd: v.trim() || undefined });
3897
3926
  return;
3898
3927
  }
@@ -323,9 +323,9 @@ export function buildSettingsRows(
323
323
  id: "notifyCmd",
324
324
  section: "other",
325
325
  label: "Notify command",
326
- valueText: show("notifyCmd", "off"),
326
+ valueText: show("notifyCmd", "auto"),
327
327
  sourceText: src("notifyCmd"),
328
- description: "desktop push command; the event message is passed as $1",
328
+ description: "custom command ($1 = message) · unset = auto-detect notify-send/osascript · 'off' = silent",
329
329
  },
330
330
  {
331
331
  id: "tokenLimit",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-goal-list-loop-audit",
3
- "version": "0.28.33",
3
+ "version": "0.28.34",
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",