pi-goal-list-loop-audit 0.18.1 → 0.19.0

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
@@ -41,11 +41,11 @@ Four top-level commands, that's all:
41
41
  /goal tweak "<new objective>" # edit in place (Confirm dialog)
42
42
  /goal archive # archived goals, newest first
43
43
  /glla # open the settings UI (or /glla key=value)
44
- /list fix the login bug, add dark mode, write docs # dump it — the agent decomposes into items, one Confirm
45
- /list add # draft a contract (or a whole batch via items[])
46
- /list add "<objective>" # queue one directly no interview (the /goal start of lists)
47
- /list add plan.md # file detectedbulk import, one Confirm
48
- /list add <paste a checklist> # multi-line paste same batch flow
44
+ /list fix the login bug, add dark mode, write docs # dump it — the agent shapes it into items, one Confirm
45
+ /list plan.md # file detected bulk import, one Confirm (sisyphus/Ralph style)
46
+ /list <paste a checklist> # multi-line paste same batch flow
47
+ /list "fix the flaky test. Done when: npm test green" # explicit contractqueues directly, no interview
48
+ /list # show the list (add/import are optional no-op aliases detection routes everything)
49
49
 
50
50
  (Or just say it: "queue these 10 things…" — the agent manages the list too.)
51
51
 
@@ -82,9 +82,9 @@ ONE confirmed batch, not 50 dialogs.
82
82
  Note: every queue item is audited individually, so at hundreds of items the
83
83
  audit cost per item is the thing to think about.
84
84
 
85
- **Drafting is the default for long-running things.** `/goal`, `/list add`, and
86
- `/loop` with no arguments all start a grilling turn that ends in a Confirm
87
- dialog. For `/loop` specifically, the orchestrator **test-runs the proposed
85
+ **Drafting is the default for long-running things.** `/goal` and
86
+ `/loop` with no arguments and any vague `/list` dump all start a
87
+ grilling turn that ends in a Confirm dialog. For `/loop` specifically, the orchestrator **test-runs the proposed
88
88
  measure command once** and shows the real number in the dialog — you validate
89
89
  the metric before a single iteration burns tokens.
90
90
 
@@ -132,8 +132,8 @@ redirect you to `/goal`.
132
132
  | Loop | Command | Status |
133
133
  |---|---|---|
134
134
  | 1. Single ordered goal | `/goal "<objective>"` | **shipped v0.1.0** |
135
- | 2. Queue of goals | `/list add\|show\|next\|remove\|clear` | **shipped v0.2.0** |
136
- | 3. Forever-polish loop | `/loop start\|status\|stop` | **shipped v0.3.0** |
135
+ | 2. Queue of goals | `/list [show\|next\|remove\|clear]` | **shipped v0.2.0** |
136
+ | 3. Metric-driven process loop | `/loop start\|status\|stop` | **shipped v0.3.0** |
137
137
 
138
138
  Each loop is a different policy class on the same status machine.
139
139
 
@@ -33,7 +33,7 @@ import {
33
33
  DEFAULT_TOKEN_LIMIT,
34
34
  mergeSettings,
35
35
  parseListImport,
36
- resolveImportFile,
36
+
37
37
  routeGoalArgs,
38
38
  routeListText,
39
39
  listMutationBlocked,
@@ -437,7 +437,7 @@ async function startDrafting(ctx: ExtensionContext, target: "goal" | "list" | "l
437
437
  const [file, label, tool] = prompts[target]!;
438
438
  ctx.ui.notify(
439
439
  seed
440
- ? `${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: ${target === "list" ? "/list add <objective>" : "/goal start <objective>"}.`
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>."}`
441
441
  : `${label} started. The agent will grill until the contract is concrete, then ${tool} opens a Confirm dialog. No work begins before confirmation.`,
442
442
  "info",
443
443
  );
@@ -727,7 +727,7 @@ async function cmdList(args: string, ctx: ExtensionContext): Promise<void> {
727
727
  lines.push("Active: (none)");
728
728
  }
729
729
  if (queue.length === 0) {
730
- lines.push("List: empty. /list <describe your tasks> | /list add <one item, no interview> | /list add <file>");
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
732
  lines.push(`Queue (${queue.length}):`);
733
733
  const PAGE = 15;
@@ -741,43 +741,33 @@ async function cmdList(args: string, ctx: ExtensionContext): Promise<void> {
741
741
  }
742
742
 
743
743
 
744
- if (sub === "import") {
745
- // Backwards-compat alias (0.8.1 shipped it; 0.8.2 folded it into add).
746
- const abs = resolveImportFile(ctx.cwd, rest.replace(/^["']|["']$/g, ""));
747
- if (!abs) {
748
- ctx.ui.notify("Usage: /list add <path> file detection is automatic now; 'import' is just an alias", "info");
744
+ // v0.19.0: `add` and `import` are pure no-op aliases — the verb changes
745
+ // nothing, detection routes everything. `/list plan.md` and
746
+ // `/list add plan.md` both import; `/list fix x, do y` and
747
+ // `/list add fix x, do y` both draft. Rationale: a list item activates
748
+ // RAW when it reaches the head, so the drafting interview is the only
749
+ // quality gate an item ever gets — a verb whose only job was skipping
750
+ // that gate was a leak, not an escape hatch. The direct path is an
751
+ // explicit "Done when:" clause (user already did the contract work).
752
+ if (sub === "add" || sub === "import") {
753
+ if (!rest) {
754
+ await startDrafting(ctx, "list");
749
755
  return;
750
756
  }
751
- await bulkAddFromFile(ctx, abs);
752
- return;
753
- }
754
-
755
- if (sub === "add") {
756
- let raw = rest;
757
- if (raw.length >= 2 && ((raw.startsWith('"') && raw.endsWith('"')) || (raw.startsWith("'") && raw.endsWith("'")))) {
758
- raw = raw.slice(1, -1).trim();
759
- }
760
- if (!raw) {
761
- // /list add with no args → draft a confirmed contract INTO THE QUEUE.
762
- await startDrafting(ctx, "list");
757
+ const aliased = routeListText(ctx.cwd, rest.replace(/^["']|["']$/g, ""));
758
+ if (aliased.kind === "file") {
759
+ await bulkAddFromFile(ctx, aliased.path);
763
760
  return;
764
761
  }
765
- // Explicit verb = explicit intent (the /goal start of lists): file and
766
- // multi-line structure are still honored, but vague text adds AS ONE
767
- // ITEM — no interview. The conversational path is bare /list <text>.
768
- const importFile = resolveImportFile(ctx.cwd, raw);
769
- if (importFile) {
770
- await bulkAddFromFile(ctx, importFile);
762
+ if (aliased.kind === "batch") {
763
+ await bulkAddItems(ctx, aliased.items, "pasted text");
771
764
  return;
772
765
  }
773
- if (raw.includes("\n")) {
774
- const pasted = parseListImport(raw);
775
- if (pasted.length > 1) {
776
- await bulkAddItems(ctx, pasted, "pasted text");
777
- return;
778
- }
766
+ if (aliased.kind === "direct") {
767
+ addSingleItem(ctx, aliased.text);
768
+ return;
779
769
  }
780
- addSingleItem(ctx, raw);
770
+ await startDrafting(ctx, "list", aliased.seed);
781
771
  return;
782
772
  }
783
773
 
@@ -2206,7 +2196,7 @@ export default function (pi: ExtensionAPI): void {
2206
2196
  handler: settingsHandler,
2207
2197
  });
2208
2198
  pi.registerCommand("list", {
2209
- description: "Loop 2: the list of audited goals — order is the default, not the law. /list <describe your tasks> (agent decomposes into items, one Confirm) | /list add <item or file> (direct, no interview) | /list show | /list next [n] | /list remove <n> | /list clear",
2199
+ 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",
2210
2200
  handler: (args: string, ctx: ExtensionContext) => { rememberCtx(ctx); return cmdList(args, ctx); },
2211
2201
  });
2212
2202
  pi.registerCommand("loop", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-goal-list-loop-audit",
3
- "version": "0.18.1",
3
+ "version": "0.19.0",
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",