pi-goal-list-loop-audit 0.19.1 → 0.19.2
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
|
|
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
|
|
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:
|
|
70
|
+
return `glla: ${g.policy} ●${tasks} ${fmtElapsed(now - Date.parse(g.createdAt))}${queue}`;
|
|
71
71
|
}
|
|
72
72
|
return undefined; // complete/aborted → clear
|
|
73
73
|
}
|
package/extensions/loops/goal.ts
CHANGED
|
@@ -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
|
|
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(`
|
|
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 (
|
|
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 (
|
|
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(`
|
|
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 /
|
|
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 /
|
|
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 /
|
|
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 /
|
|
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
|
-
// /
|
|
2023
|
-
// /
|
|
2024
|
-
// /
|
|
2025
|
-
// /
|
|
2026
|
-
// /
|
|
2027
|
-
// /
|
|
2028
|
-
// /
|
|
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: /
|
|
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: /
|
|
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
|
-
// /
|
|
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; /
|
|
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: "/
|
|
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()}). /
|
|
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.
|
|
3
|
+
"version": "0.19.2",
|
|
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",
|