pi-goal-list-loop-audit 0.19.1 → 0.19.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.
@@ -202,7 +202,7 @@ export function parseListImport(content: string): string[] {
202
202
  }
203
203
 
204
204
  /**
205
- * During a LIST drafting session the agent must not queue items one by one
205
+ * During a LIST drafting session the agent must not add items one by one
206
206
  * with list_add/list_activate — that bypasses the user's Confirm gate
207
207
  * (observed in the wild: the agent decomposed a dump and ACTIVATED the first
208
208
  * item with zero confirmation). The batch path is propose_goal_draft's
@@ -214,7 +214,7 @@ export function listMutationBlocked(draftingTarget: string | null): boolean {
214
214
  }
215
215
 
216
216
  export const LIST_DRAFTING_BLOCK_MESSAGE =
217
- "LIST DRAFTING IN PROGRESS — do not queue items one by one. Decompose the request into an items[] array and call propose_goal_draft ONCE: the user confirms the whole batch in a single dialog. list_add / list_activate work again after the drafting session ends.";
217
+ "LIST DRAFTING IN PROGRESS — do not add items one by one. Decompose the request into an items[] array and call propose_goal_draft ONCE: the user confirms the whole batch in a single dialog. list_add / list_activate work again after the drafting session ends.";
218
218
 
219
219
  /**
220
220
  * Route natural-language text handed to `/list` with no subcommand verb
@@ -67,7 +67,7 @@ export function buildStatusText(state: State, audit?: AuditDisplayProgress | nul
67
67
  if (g.status === "active") {
68
68
  const queue = state.list?.length ? ` · list ${state.list.length}` : "";
69
69
  const tasks = g.taskList ? ` ${countDone(g)}/${countTotal(g)} tasks ·` : "";
70
- return `glla: goal ●${tasks} ${fmtElapsed(now - Date.parse(g.createdAt))}${queue}`;
70
+ return `glla: ${g.policy} ●${tasks} ${fmtElapsed(now - Date.parse(g.createdAt))}${queue}`;
71
71
  }
72
72
  return undefined; // complete/aborted → clear
73
73
  }
@@ -431,7 +431,7 @@ async function startDrafting(ctx: ExtensionContext, target: "goal" | "list" | "l
431
431
  draftingTarget = target;
432
432
  const prompts: Record<string, [string, string, string]> = {
433
433
  goal: ["goal-loop-draft.md", "Goal drafting", "propose_goal_draft"],
434
- list: ["goal-loop-draft.md", "Goal drafting (for the queue)", "propose_goal_draft"],
434
+ list: ["goal-loop-draft.md", "Goal drafting (for the list)", "propose_goal_draft"],
435
435
  loop: ["goal-loop-forever-draft.md", "Loop drafting", "propose_loop_draft"],
436
436
  };
437
437
  const [file, label, tool] = prompts[target]!;
@@ -729,7 +729,7 @@ async function cmdList(args: string, ctx: ExtensionContext): Promise<void> {
729
729
  if (queue.length === 0) {
730
730
  lines.push("List: empty. /list <describe your tasks, or a plan file> — the agent shapes dumps into items, files import directly.");
731
731
  } else {
732
- lines.push(`Queue (${queue.length}):`);
732
+ lines.push(`List (${queue.length}):`);
733
733
  const PAGE = 15;
734
734
  queue.slice(0, PAGE).forEach((item, i) => lines.push(` ${i + 1}. ${item.objective.slice(0, 90)}`));
735
735
  if (queue.length > PAGE) {
@@ -1491,7 +1491,7 @@ function registerAgentTools(pi: any, ctx: ExtensionContext): void {
1491
1491
  const wasIdle = !state.goal || state.goal.status === "complete" || state.goal.status === "aborted";
1492
1492
  const n = enqueueItems(liveCtx, p.items, "drafted batch");
1493
1493
  if (wasIdle) {
1494
- return { content: [{ type: "text", text: `${n} items confirmed; first activated (queue was empty). Begin work now.` }], details: {} };
1494
+ return { content: [{ type: "text", text: `${n} items confirmed; first activated (list was empty). Begin work now.` }], details: {} };
1495
1495
  }
1496
1496
  return { content: [{ type: "text", text: `${n} items confirmed and queued (${listQueue().length} waiting).` }], details: {} };
1497
1497
  }
@@ -1522,7 +1522,7 @@ function registerAgentTools(pi: any, ctx: ExtensionContext): void {
1522
1522
  appendLedger(liveCtx.cwd, "list_added", { id: item.id, objective: item.objective, drafted: true });
1523
1523
  if (!state.goal || state.goal.status === "complete" || state.goal.status === "aborted") {
1524
1524
  activateNextListItem(liveCtx);
1525
- return { content: [{ type: "text", text: "Confirmed and activated (queue was empty). Begin work now." }], details: {} };
1525
+ return { content: [{ type: "text", text: "Confirmed and activated (list was empty). Begin work now." }], details: {} };
1526
1526
  }
1527
1527
  return { content: [{ type: "text", text: `Confirmed and queued (${listQueue().length} waiting). It activates when the current goal completes.` }], details: {} };
1528
1528
  }
@@ -1772,7 +1772,7 @@ function registerAgentTools(pi: any, ctx: ExtensionContext): void {
1772
1772
  if (queue.length === 0) {
1773
1773
  lines.push("List: empty.");
1774
1774
  } else {
1775
- lines.push(`Queue (${queue.length}):`);
1775
+ lines.push(`List (${queue.length}):`);
1776
1776
  queue.slice(0, 20).forEach((item, i) => lines.push(`${i + 1}. ${item.objective}`));
1777
1777
  if (queue.length > 20) lines.push(`… and ${queue.length - 20} more`);
1778
1778
  }
@@ -1952,20 +1952,20 @@ function resolveAuditorModel(ctx: ExtensionContext, ref?: string): { model: any;
1952
1952
  }
1953
1953
  const sessionModel = ctx.model as any;
1954
1954
  if (sessionModel) return { model: sessionModel, via: "session" };
1955
- return { model: undefined, error: "no session model and no auditorModel configured — set one with /gla model=provider/id" };
1955
+ return { model: undefined, error: "no session model and no auditorModel configured — set one with /glla model=provider/id" };
1956
1956
  }
1957
1957
 
1958
1958
  // (v0.9.12) The auto-fallback apparatus was REMOVED: no tier ranking, no
1959
1959
  // candidate chains, no dead-model caches. The plugin never picks a model —
1960
- // you select it in pi (session model) or in /gla (explicit override). When
1960
+ // you select it in pi (session model) or in /glla (explicit override). When
1961
1961
  // neither works, the failure surfaces plainly (see the three-way split in
1962
1962
  // the complete_goal handler) with the exact fix; nothing is substituted
1963
1963
  // silently.
1964
1964
 
1965
1965
  /**
1966
- * The /gla interactive settings UI (v0.8.0): a menu loop over pi's dialog
1966
+ * The /glla interactive settings UI (v0.8.0): a menu loop over pi's dialog
1967
1967
  * primitives. Pick a setting → edit it → saved to GLOBAL → back to the menu.
1968
- * Done/Esc exits. Rarely opened by design; scriptable /gla key=value remains
1968
+ * Done/Esc exits. Rarely opened by design; scriptable /glla key=value remains
1969
1969
  * for tmux/headless.
1970
1970
  */
1971
1971
  async function openSettingsUI(ctx: ExtensionContext): Promise<void> {
@@ -2019,13 +2019,13 @@ async function openSettingsUI(ctx: ExtensionContext): Promise<void> {
2019
2019
 
2020
2020
  async function cmdSettings(args: string, ctx: ExtensionContext): Promise<void> {
2021
2021
  // The plugin's ONE config surface — global by default, rarely opened.
2022
- // /gla show effective values + where each comes from
2023
- // /gla model=provider/id write to GLOBAL config
2024
- // /gla thinking=high write to GLOBAL config
2025
- // /gla notify='cmd $1' write to GLOBAL config
2026
- // /gla tokenlimit=2000000 write to GLOBAL config
2027
- // /gla project model=... write to PROJECT override (rare)
2028
- // /gla model=unset remove key (from global; project model=unset for project)
2022
+ // /glla show effective values + where each comes from
2023
+ // /glla model=provider/id write to GLOBAL config
2024
+ // /glla thinking=high write to GLOBAL config
2025
+ // /glla notify='cmd $1' write to GLOBAL config
2026
+ // /glla tokenlimit=2000000 write to GLOBAL config
2027
+ // /glla project model=... write to PROJECT override (rare)
2028
+ // /glla model=unset remove key (from global; project model=unset for project)
2029
2029
  const trimmed = args.trim();
2030
2030
  if (!trimmed) {
2031
2031
  if (ctx.hasUI) {
@@ -2047,7 +2047,7 @@ async function cmdSettings(args: string, ctx: ExtensionContext): Promise<void> {
2047
2047
  fmt("tokenLimit", "tokenLimit"),
2048
2048
  `\nglobal: ${globalSettingsPath()}`,
2049
2049
  `project: ${projectSettingsPath(ctx.cwd)}`,
2050
- `Set with: /gla key=value (global) · /gla project key=value (project override)`,
2050
+ `Set with: /glla key=value (global) · /glla project key=value (project override)`,
2051
2051
  ].join("\n"),
2052
2052
  "info",
2053
2053
  );
@@ -2137,7 +2137,7 @@ function warnIfAuditorProviderRisky(ctx: ExtensionContext): void {
2137
2137
  const provider = (ctx.model as any)?.provider as string | undefined;
2138
2138
  if (!provider || KNOWN_BUILTIN_PROVIDERS.has(provider)) return;
2139
2139
  ctx.ui.notify(
2140
- `pi-goal-list-loop-audit: session provider "${provider}" is extension-registered — the auditor (extension-less session) will fail auth with it. If audits error, set a built-in override once: /gla model=provider/id`,
2140
+ `pi-goal-list-loop-audit: session provider "${provider}" is extension-registered — the auditor (extension-less session) will fail auth with it. If audits error, set a built-in override once: /glla model=provider/id`,
2141
2141
  "info",
2142
2142
  );
2143
2143
  } catch {
@@ -2182,7 +2182,7 @@ export default function (pi: ExtensionAPI): void {
2182
2182
  // /goal — set/draft + status|pause|resume|cancel|tweak|archive subcommands
2183
2183
  // /list — the list (add|show|next|remove|clear)
2184
2184
  // /loop — the metric loop (draft|start|status|stop)
2185
- // /gla — the settings UI (+ scriptable key=value)
2185
+ // /glla — the settings UI (+ scriptable key=value)
2186
2186
  pi.registerCommand("goal", {
2187
2187
  description: "Set/draft a goal, or /goal status|pause|resume|cancel|tweak <text>|archive|start <objective>. Objectives without a 'Done when:' clause are grilled into a contract first; include the clause or use /goal start to skip the interview and activate instantly.",
2188
2188
  handler: (args: string, ctx: ExtensionContext) => { rememberCtx(ctx); return cmdGoal(args, ctx); },
@@ -2311,7 +2311,7 @@ export default function (pi: ExtensionAPI): void {
2311
2311
 
2312
2312
  // Token accounting + cost guard: accumulate this turn's assistant tokens
2313
2313
  // (deduped — agent_end may replay seen messages). Crossing the goal's
2314
- // token limit pauses it; /gla tokenlimit=<n> to raise.
2314
+ // token limit pauses it; /glla tokenlimit=<n> to raise.
2315
2315
  const newTokens = sumNewAssistantTokens(event.messages as unknown[], countedTokenMessages);
2316
2316
  if (newTokens > 0) {
2317
2317
  const used = (state.goal.usage?.tokensUsed ?? 0) + newTokens;
@@ -2322,9 +2322,9 @@ export default function (pi: ExtensionAPI): void {
2322
2322
  usage: { tokensUsed: used, tokensLimit: limit },
2323
2323
  status: "paused",
2324
2324
  pauseReason: `token limit exceeded (${used.toLocaleString()} > ${limit.toLocaleString()})`,
2325
- pauseSuggestedAction: "/gla tokenlimit=<n> to raise the cap (or 0 to disable), then /goal resume",
2325
+ pauseSuggestedAction: "/glla tokenlimit=<n> to raise the cap (or 0 to disable), then /goal resume",
2326
2326
  }, ctx);
2327
- ctx.ui.notify(`Goal paused: token limit exceeded (${used.toLocaleString()} > ${limit.toLocaleString()}). /gla tokenlimit=<n> to raise, 0 to disable.`, "warning");
2327
+ ctx.ui.notify(`Goal paused: token limit exceeded (${used.toLocaleString()} > ${limit.toLocaleString()}). /glla tokenlimit=<n> to raise, 0 to disable.`, "warning");
2328
2328
  notifyExternal(ctx, `Goal paused: token limit exceeded (${used} > ${limit}).`);
2329
2329
  return;
2330
2330
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-goal-list-loop-audit",
3
- "version": "0.19.1",
3
+ "version": "0.19.3",
4
4
  "description": "Goal. Loop. Audit. Done. — 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 — only the read tools needed to verify your goal.",
5
5
  "license": "MIT",
6
6
  "author": "dracon",
@@ -25,10 +25,17 @@ request into a **confirmed goal contract**. Do NOT start substantive work yet.
25
25
  enough that a skeptical auditor could verify them from raw evidence.
26
26
  "Make it better" is not a goal. "Reduce `npm test` failures from 14 to 0"
27
27
  is.
28
- 5. When concrete, call `propose_goal_draft` with `objective` and
28
+ 5. Scope thoroughness INTO the contract, never into iteration budgets. A
29
+ goal has no iterations and no stop rules — it ends when the auditor
30
+ approves. If the user wants exhaustiveness, write it as checkable
31
+ contract items ("Done when: all 22 settings screens audited"), not as
32
+ "N passes". Iterations / plateau / window are `/loop` vocabulary; do not
33
+ import them here, and do not present invented pass-counts as packaged
34
+ tiers.
35
+ 6. When concrete, call `propose_goal_draft` with `objective` and
29
36
  `verificationContract`. That opens the user's **Confirm dialog** —
30
37
  nothing activates until they confirm.
31
- 6. If the user rejects the draft, refine based on their feedback and
38
+ 7. If the user rejects the draft, refine based on their feedback and
32
39
  propose again. Do not call `propose_goal_draft` repeatedly without
33
40
  changing anything.
34
41