pi-goal-list-loop-audit 0.22.3 → 0.22.5

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.
@@ -435,9 +435,15 @@ async function startDrafting(ctx: ExtensionContext, target: "goal" | "list" | "l
435
435
  loop: ["goal-loop-forever-draft.md", "Loop drafting", "propose_loop_draft"],
436
436
  };
437
437
  const [file, label, tool] = prompts[target]!;
438
+ const seededHint =
439
+ target === "list"
440
+ ? `${label}: the objective has no "Done when:" clause — the agent will grill you about it first (nothing activates until you confirm). Add directly instead: include a "Done when:" clause.`
441
+ : target === "loop"
442
+ ? `${label}: a loop target needs a metric and a direction — the agent will help you design them first (nothing activates until you confirm). Skip the interview entirely: /loop start "<target>" measure="<cmd>" direction=min|max [window=5] [max=50] [time=h] [tokens=n] [branch=1].`
443
+ : `${label}: the objective has no "Done when:" clause — the agent will grill you about it first (nothing activates until you confirm). Skip the interview entirely: /goal start <objective>.`;
438
444
  ctx.ui.notify(
439
445
  seed
440
- ? `${label}: the objective has no "Done when:" clause — the agent will grill you about it first (nothing activates until you confirm). ${target === "list" ? "Add directly instead: include a \"Done when:\" clause." : "Skip the interview entirely: /goal start <objective>."}`
446
+ ? seededHint
441
447
  : `${label} started. The agent will grill until the contract is concrete, then ${tool} opens a Confirm dialog. No work begins before confirmation.`,
442
448
  "info",
443
449
  );
@@ -572,6 +578,13 @@ async function cmdResume(ctx: ExtensionContext): Promise<void> {
572
578
  ? { tokensUsed: state.goal.usage.tokensUsed, tokensLimit: freshLimit }
573
579
  : undefined;
574
580
  updateGoal({ status: "active", pauseReason: undefined, pauseSuggestedAction: undefined, ...(usage ? { usage } : {}) }, ctx);
581
+ // v0.22.5: say what was resumed — with a non-empty list this also resumes
582
+ // the queue (the active goal IS the list's head item).
583
+ const queued = listQueue().length;
584
+ ctx.ui.notify(
585
+ `Resumed goal [${state.goal.id}]: ${state.goal.objective.replace(/\s+/g, " ").slice(0, 70)}${queued > 0 ? ` (+${queued} queued in the list — resuming the list's head)` : ""}`,
586
+ "info",
587
+ );
575
588
  scheduleContinuation(ctx, true);
576
589
  }
577
590
 
@@ -1228,7 +1241,15 @@ async function cmdLoop(args: string, ctx: ExtensionContext): Promise<void> {
1228
1241
  return;
1229
1242
  }
1230
1243
 
1231
- ctx.ui.notify("Usage: /loop [status] | /loop start \"<target>\" measure=\"<cmd>\" direction=min|max [window=5] [max=50] | /loop stop", "info");
1244
+ // Anything else is a natural-language target (v0.22.4): draft it the
1245
+ // metric is the whole game for a loop, and /loop start with full params
1246
+ // is the skip-drafting path. Previously this fell through to a usage
1247
+ // line, so "/loop make the tests faster" did nothing useful.
1248
+ if (isLoopActive()) {
1249
+ ctx.ui.notify("A loop is already active — /loop status to inspect, /loop stop to end it.", "info");
1250
+ return;
1251
+ }
1252
+ await startDrafting(ctx, "loop", args.trim());
1232
1253
  }
1233
1254
 
1234
1255
  // =================================================================
@@ -2211,21 +2232,55 @@ export default function (pi: ExtensionAPI): void {
2211
2232
  // /list — the list (add|show|next|remove|clear)
2212
2233
  // /loop — the metric loop (draft|start|status|stop)
2213
2234
  // /glla — the settings UI (+ scriptable key=value)
2235
+ // v0.22.5: subcommand autocomplete for the /-menu.
2236
+ const completions = (items: Array<[string, string]>) => (prefix: string) =>
2237
+ items
2238
+ .filter(([value]) => value.startsWith(prefix))
2239
+ .map(([value, description]) => ({ value, label: value, description }));
2240
+
2214
2241
  pi.registerCommand("goal", {
2215
2242
  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.",
2243
+ getArgumentCompletions: completions([
2244
+ ["start", "skip drafting — /goal start <objective> activates immediately"],
2245
+ ["status", "show the active goal and its task list"],
2246
+ ["pause", "pause the active goal"],
2247
+ ["resume", "resume a paused goal (and the list, when items are queued)"],
2248
+ ["cancel", "abort the active goal"],
2249
+ ["tweak", "change the objective: /goal tweak <text>"],
2250
+ ["archive", "list archived goals"],
2251
+ ]),
2216
2252
  handler: (args: string, ctx: ExtensionContext) => { rememberCtx(ctx); return cmdGoal(args, ctx); },
2217
2253
  });
2218
2254
  const settingsHandler = (args: string, ctx: ExtensionContext) => { rememberCtx(ctx); return cmdSettings(args, ctx); };
2219
2255
  pi.registerCommand("glla", {
2220
2256
  description: "Open the settings UI for goals, loops, lists, and the auditor. Scriptable form: /glla key=value · /glla project key=value",
2257
+ getArgumentCompletions: completions([
2258
+ ["model=", "auditor model override: /glla model=provider/id"],
2259
+ ["thinking=", "auditor thinking level: /glla thinking=high"],
2260
+ ["notify=", "desktop push command: /glla notify='notify-send pi \"$1\"'"],
2261
+ ["tokenlimit=", "per-goal token budget (0 = off): /glla tokenlimit=2000000"],
2262
+ ["autoresume=", "on: auto-resume held goals/loops in fresh sessions"],
2263
+ ["project", "write a project override: /glla project key=value"],
2264
+ ]),
2221
2265
  handler: settingsHandler,
2222
2266
  });
2223
2267
  pi.registerCommand("list", {
2224
2268
  description: "Loop 2: the list of audited goals — order is the default, not the law. /list <describe tasks or name a plan file> (dumps get shaped into items, files import, 'Done when:' adds directly) | /list show | /list next [n] | /list remove <n> | /list clear",
2269
+ getArgumentCompletions: completions([
2270
+ ["show", "display the queued items"],
2271
+ ["next", "activate the next item (or /list next <n> for position n)"],
2272
+ ["remove", "remove an item: /list remove <n>"],
2273
+ ["clear", "empty the list"],
2274
+ ]),
2225
2275
  handler: (args: string, ctx: ExtensionContext) => { rememberCtx(ctx); return cmdList(args, ctx); },
2226
2276
  });
2227
2277
  pi.registerCommand("loop", {
2228
- description: "Loop 3: metric-driven process — it never completes. /loop start \"<target>\" measure=\"<cmd>\" direction=min|max [window=5] [max=50] [time=<hours>] [tokens=<budget>] [branch=1] | /loop status | /loop stop. 'Improve until X' is a /goal, not a loop.",
2278
+ description: "Loop 3: metric-driven process — it never completes. /loop <target> drafts the metric with you · /loop start \"<target>\" measure=\"<cmd>\" direction=min|max [window=5] [max=50] [time=<hours>] [tokens=<budget>] [branch=1] skips drafting · /loop status · /loop stop. 'Improve until X' is a /goal, not a loop.",
2279
+ getArgumentCompletions: completions([
2280
+ ["start", "skip drafting: /loop start \"<target>\" measure=\"<cmd>\" direction=min|max [window=5] [max=50]"],
2281
+ ["status", "show metric, iteration, best/last values, stall count"],
2282
+ ["stop", "end the loop (keeps the best state)"],
2283
+ ]),
2229
2284
  handler: (args: string, ctx: ExtensionContext) => { rememberCtx(ctx); return cmdLoop(args, ctx); },
2230
2285
  });
2231
2286
 
@@ -2295,13 +2350,17 @@ export default function (pi: ExtensionAPI): void {
2295
2350
  );
2296
2351
  scheduleContinuation(ctx, true);
2297
2352
  } else {
2353
+ const queued = listQueue().length;
2354
+ const resumeHint = queued > 0
2355
+ ? `/goal resume to continue (+${queued} queued in the list) · /glla autoresume=on to auto-resume in this project`
2356
+ : "/goal resume to continue · /glla autoresume=on to auto-resume in this project";
2298
2357
  updateGoal({
2299
2358
  status: "paused",
2300
2359
  pauseReason: "restored in a fresh session — no work started",
2301
- pauseSuggestedAction: "/goal resume to continue · /glla autoresume=on to auto-resume in this project",
2360
+ pauseSuggestedAction: resumeHint,
2302
2361
  }, ctx);
2303
2362
  ctx.ui.notify(
2304
- `Goal held on restore [${state.goal.id}]: ${state.goal.objective.slice(0, 70)} — /goal resume to continue.`,
2363
+ `Goal held on restore [${state.goal.id}]: ${state.goal.objective.slice(0, 70)}${queued > 0 ? ` (+${queued} queued in the list)` : ""} — /goal resume to continue.`,
2305
2364
  "info",
2306
2365
  );
2307
2366
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-goal-list-loop-audit",
3
- "version": "0.22.3",
3
+ "version": "0.22.5",
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",