ready menu: print the plan, add "Ready + compact"

"Ready?" over an unread file is not a review -- the only copy of the plan was
inside a collapsed edit tool call. Print the working set before the menu.

The 4th option compacts the planning conversation before the work turn starts.
session_compact already re-sends the whole plan file, so the exploration is
summarized away and the agreed goals are not.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
This commit is contained in:
wassname
2026-08-21 08:14:29 +08:00
co-authored by Claudypoo
parent d5766c1a34
commit 3a1afd4c8e
2 changed files with 31 additions and 8 deletions
+4 -2
View File
@@ -55,8 +55,10 @@ pi -e ./src/index.ts
1. Plan. The agent explores read-only (edit/write are blocked except on the plan file itself), asks
about anything unclear, and drafts the goals into this session's plan file. The drafting rules
are sent once, with your objective, not re-sent every turn.
2. Review. Read the file; a menu asks Ready, open in `$EDITOR`, or keep planning. To revise, just
reply. Plan mode ends when you pick Ready.
2. Review. The working set is printed in the transcript, then a menu asks Ready, Ready + compact,
open in `$EDITOR`, or keep planning. To revise, just reply. Plan mode ends when you pick a Ready.
Ready + compact summarizes the planning conversation away first; the plan file comes back whole
on the next turn, so nothing you agreed is lost.
3. Work. The agent ticks subtasks, appends to `## Log` and `## Learnings`, fills `evidence:`, and
calls `CompleteGoal` when a discriminator is satisfied. If it leaves the plan untouched for two
turns, the working set is sent back with a short upkeep reminder.
+27 -6
View File
@@ -258,13 +258,22 @@ export default function piGoalsExtension(pi: ExtensionAPI): void {
}
});
// After a plan-mode turn: if goals were drafted, offer Ready. The human reads the file and says
// go, edits it in $EDITOR, or keeps talking to revise it (menu shape borrowed from pi-plan).
// After a plan-mode turn: if goals were drafted, print the working set and offer Ready. The plan
// is printed because "Ready?" over an unread file is not a review: the only other copy is inside
// a collapsed edit tool call. Reprinted after an $EDITOR pass only if the text changed.
// The human then says go, edits it, or keeps talking to revise it (menu shape borrowed from pi-plan).
pi.on("agent_end", async (_event, ctx) => {
if (!state.isPlanMode || !ctx.hasUI) return;
let printed = "";
while (scanGoals(readPlan(ctx)).length > 0) {
const working = foldPlan(readPlan(ctx));
if (working !== printed) {
printed = working;
pi.sendMessage({ customType: "plan", content: working, display: true });
}
const choice = await ctx.ui.select(`Plan drafted in ${planRel(ctx)}. Ready?`, [
"Ready — start working the plan",
"Ready + compact — the same, but summarize the planning chatter away first",
"Open in $EDITOR — edit it myself",
"Keep planning (reply to revise)",
]);
@@ -276,10 +285,22 @@ export default function piGoalsExtension(pi: ExtensionAPI): void {
state = { ...state, isPlanMode: false };
persist();
updateWidget(ctx);
pi.sendUserMessage(
`Work the goals in ${planPath(ctx)}. Pick an open goal, mark it active ([/]), work its subtasks, and when its discriminator is satisfied fill its evidence: list, then call CompleteGoal with the goal's text. Keep the plan file current as you go.`,
{ deliverAs: "followUp" },
);
const work = `Work the goals in ${planPath(ctx)}. Pick an open goal, mark it active ([/]), work its subtasks, and when its discriminator is satisfied fill its evidence: list, then call CompleteGoal with the goal's text. Keep the plan file current as you go.`;
if (!choice.includes("compact")) {
pi.sendUserMessage(work, { deliverAs: "followUp" });
return;
}
// Compaction fires session_compact, so the whole plan file comes back on the next call --
// the exploration is summarized away, the agreed goals are not. Sent from onComplete so
// the work turn starts after the summary exists; a failed compaction still starts work.
ctx.compact({
customInstructions: `Planning is finished. Keep what ${planRel(ctx)} depends on: the objective, the human's constraints, and what was ruled out and why. The read-only exploration that produced them can go.`,
onComplete: () => pi.sendUserMessage(work, { deliverAs: "followUp" }),
onError: (e) => {
ctx.ui.notify(`Compaction failed (${e.message}); starting work anyway.`, "warning");
pi.sendUserMessage(work, { deliverAs: "followUp" });
},
});
return;
}
});