@narumitw/pi-goal 0.1.18 → 0.1.19

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.
Files changed (3) hide show
  1. package/README.md +4 -4
  2. package/package.json +1 -1
  3. package/src/goal.ts +18 -9
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  `@narumitw/pi-goal` is a native [Pi coding agent](https://pi.dev) extension that adds session-scoped `/goal` commands and a `goal_complete` tool for autonomous, verifiable task completion.
6
6
 
7
- Goal mode keeps sending guarded automatic follow-up messages until the agent calls `goal_complete`, the user pauses or clears the goal, or an optional token budget is reached.
7
+ Goal mode uses Codex-like persistence instructions and keeps sending guarded continuation messages until the agent calls `goal_complete`, the user pauses or clears the goal, or an optional token budget is reached.
8
8
 
9
9
  ## ✨ Features
10
10
 
@@ -16,7 +16,7 @@ Goal mode keeps sending guarded automatic follow-up messages until the agent cal
16
16
  - Tracks `active`, `paused`, `budget_limited`, and `complete` states.
17
17
  - Stores goal state in the current Pi session, following Codex's thread-owned goal model instead of using a global per-directory goal.
18
18
  - Registers a `goal_complete` tool for explicit completion.
19
- - Automatically prompts the agent to continue if an active turn ends early.
19
+ - Automatically prompts the agent to continue if an active turn ends early, directly triggering the next turn when Pi is idle.
20
20
  - Guards auto-follow-ups so replaced, paused, cleared, completed, or budget-limited goals are not continued.
21
21
  - Encourages verification before the goal is marked complete.
22
22
 
@@ -78,9 +78,9 @@ Older versions wrote unfinished goals to `~/.pi/agent/pi-goal-state.json` keyed
78
78
 
79
79
  ## ✅ How completion works
80
80
 
81
- The extension registers a `goal_complete` tool. While a goal is active, the system prompt tells the agent to keep working, verify the result, and call `goal_complete` only when the goal is fully done.
81
+ The extension registers a `goal_complete` tool. While a goal is active, the system prompt uses Codex-like persistence rules: keep going until the goal is resolved end-to-end, do not stop at analysis, a plan, partial fixes, or suggested next steps, use available tools for implementation and verification, and call `goal_complete` only when the goal is fully done.
82
82
 
83
- If an agent turn ends before `goal_complete` is called, the extension records elapsed time and token usage, checks the budget, verifies that the same goal id is still active, then sends a follow-up prompt to continue the same goal.
83
+ If an agent turn ends before `goal_complete` is called, the extension records elapsed time and token usage, checks the budget, verifies that the same goal id is still active, then sends a continuation prompt for the same goal. When Pi is already idle, this directly triggers the next turn; otherwise it is queued as a follow-up until the agent finishes current work.
84
84
 
85
85
  ## 🧠 Use cases
86
86
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@narumitw/pi-goal",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "description": "Pi extension that keeps working on a /goal until the agent marks it complete.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/goal.ts CHANGED
@@ -173,7 +173,7 @@ export default function goal(pi: ExtensionAPI) {
173
173
 
174
174
  const currentGoal = activeGoal;
175
175
  if (!currentGoal || currentGoal.id !== goalId || currentGoal.status !== "active") return;
176
- pi.sendUserMessage(buildContinuePrompt(currentGoal), { deliverAs: "followUp" });
176
+ sendContinuationPrompt(pi, ctx, currentGoal);
177
177
  });
178
178
  }
179
179
 
@@ -416,13 +416,18 @@ function validateObjective(objective: string): string | undefined {
416
416
  }
417
417
 
418
418
  function sendGoalPrompt(pi: ExtensionAPI, ctx: StatusContext, goal: ActiveGoal) {
419
- const prompt = buildGoalPrompt(goal);
420
- if (ctx.isIdle?.()) pi.sendUserMessage(prompt);
421
- else pi.sendUserMessage(prompt, { deliverAs: "followUp" });
419
+ sendPrompt(pi, ctx, buildGoalPrompt(goal));
422
420
  }
423
421
 
424
422
  function sendObjectiveUpdatedPrompt(pi: ExtensionAPI, ctx: StatusContext, goal: ActiveGoal) {
425
- const prompt = buildObjectiveUpdatedPrompt(goal);
423
+ sendPrompt(pi, ctx, buildObjectiveUpdatedPrompt(goal));
424
+ }
425
+
426
+ function sendContinuationPrompt(pi: ExtensionAPI, ctx: StatusContext, goal: ActiveGoal) {
427
+ sendPrompt(pi, ctx, buildContinuePrompt(goal));
428
+ }
429
+
430
+ function sendPrompt(pi: ExtensionAPI, ctx: StatusContext, prompt: string) {
426
431
  if (ctx.isIdle?.()) pi.sendUserMessage(prompt);
427
432
  else pi.sendUserMessage(prompt, { deliverAs: "followUp" });
428
433
  }
@@ -477,21 +482,25 @@ function formatTokenCount(value: number) {
477
482
 
478
483
  function buildGoalPrompt(goal: ActiveGoal) {
479
484
  const budgetLine = goal.tokenBudget === undefined ? "" : `\nToken budget: ${formatTokenCount(goal.tokenBudget)}.`;
480
- return `Goal mode is active. Complete this goal fully:\n\n${goal.text}${budgetLine}\n\nKeep working until the goal is done. Do not stop after planning or partial progress. When the goal is fully complete and verified, call the goal_complete tool with a concise completion summary.`;
485
+ return `Goal mode is active. Complete this goal fully:\n\n${goal.text}${budgetLine}\n\n${goalPersistenceRules("this goal")}`;
481
486
  }
482
487
 
483
488
  function buildObjectiveUpdatedPrompt(goal: ActiveGoal) {
484
489
  const budgetLine = goal.tokenBudget === undefined ? "" : `\nToken budget: ${formatBudget(goal)} used.`;
485
- return `The active /goal objective was updated. Continue working toward this goal:\n\n${goal.text}${budgetLine}\n\nKeep working until the updated goal is fully complete and verified, then call the goal_complete tool.`;
490
+ return `The active /goal objective was updated. Continue working toward this goal:\n\n${goal.text}${budgetLine}\n\n${goalPersistenceRules("the updated goal")}`;
486
491
  }
487
492
 
488
493
  function buildGoalSystemPrompt(goal: ActiveGoal) {
489
494
  const budgetLine = goal.tokenBudget === undefined ? "" : `\n- Respect the goal token budget (${formatBudget(goal)} used).`;
490
- return `Active /goal: ${goal.text}\n\nGoal-mode rules:\n- Continue making concrete progress until the active goal is fully complete.\n- Do not end your response with only a plan, TODO list, or partial progress.\n- Verify the result when possible using appropriate checks.\n- If the goal is not complete at the end of a turn, expect an automatic follow-up and continue from where you left off.\n- Only call the goal_complete tool after the goal is fully complete and verified.${budgetLine}`;
495
+ return `Active /goal: ${goal.text}\n\nGoal-mode rules:\n- Keep going until the active goal is completely resolved end-to-end.\n- Do not stop at analysis, a plan, TODO list, partial fixes, or suggested next steps.\n- Autonomously perform implementation and verification with the available tools when they are needed to complete the goal.\n- Persevere through recoverable tool failures by trying reasonable alternatives instead of yielding early.\n- If the goal is not complete at the end of a turn, expect an automatic continuation and keep working from where you left off.\n- Only call the goal_complete tool after the goal is fully complete and verified.${budgetLine}`;
491
496
  }
492
497
 
493
498
  function buildContinuePrompt(goal: ActiveGoal) {
494
- return `Continue the active /goal until it is complete:\n\n${goal.text}\n\nThis is automatic continuation #${goal.iteration}. If the goal is not complete yet, keep working and verify progress. If it is fully complete and verified, call the goal_complete tool.`;
499
+ return `Continue the active /goal until it is complete:\n\n${goal.text}\n\nThis is automatic continuation #${goal.iteration}. ${goalPersistenceRules("this goal")}`;
500
+ }
501
+
502
+ function goalPersistenceRules(goalLabel: string) {
503
+ return `Keep going until ${goalLabel} is completely resolved end-to-end. Do not stop at analysis, a plan, TODO list, partial fixes, or suggested next steps. Autonomously perform implementation and verification with the available tools when they are needed. If a tool call fails, try reasonable alternatives instead of yielding early. Only call the goal_complete tool after ${goalLabel} is fully complete and verified.`;
495
504
  }
496
505
 
497
506
  function currentTokenTotal(ctx: StatusContext): number {