pi-goal-x

Goal mode extension for pi: persistent long-running objectives, /goal-set drafting, Sisyphus prompt style, autoContinue, and an above-editor status overlay. Fork of @capyup/pi-goal.

Packages

Package details

extension

Install pi-goal-x from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:pi-goal-x
Package
pi-goal-x
Version
0.18.4
Published
May 31, 2026
Downloads
2,760/mo · 2,123/wk
Author
tmonk
License
MIT
Types
extension
Size
416 KB
Dependencies
0 dependencies · 4 peers
Pi manifest JSON
{
  "extensions": [
    "extensions/goal.ts"
  ],
  "image": "https://github.com/tmonk/pi-goal-x/raw/main/screenshot.png"
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-goal-x

Fork of @capyup/pi-goal — this repository extends the upstream with quality-of-life features for the completion auditor, lifecycle reliability improvements, mid-flight objective updates, deferred archival, and drafting UX refinements. Upstream changes can be merged from the original repository.

pi-goal-x is a long-running goal extension for pi. It gives the agent a durable objective, a visible lifecycle, and schema-gated tools for drafting, executing, pausing, resuming, and completing work.

The extension is designed around one rule: the user owns intent; the agent executes only after the goal is explicit and confirmed.

What's different from upstream

All core features of @capyup/pi-goal are preserved. The following changes are specific to pi-goal-x:

Verification contract system

  • Per-goal verification contracts — when drafting a goal, include a Verification contract: section with plain-text requirements (e.g. "Run npm test (0 failures), grep for remaining STP references"). The contract is extracted, stored on the goal record, and enforced by the complete_goal tool — the call is rejected unless the agent provides a non-empty verificationSummary matching the contract.
  • Per-task verification contractspropose_task_list supports an optional verificationContract per task. If set, complete_task requires a non-empty verificationSummary.
  • Both prompt and tool enforcement — prompts include a VERIFICATION CONTRACT section instructing the agent; tool validators reject calls that violate the contract.
  • Backward compatible — goals/tasks without a Verification contract: section work exactly as before. No contract = no enforcement.
  • Auditor integration — the independent completion auditor receives both the verificationContract and verificationSummary and cross-checks claims against real artifacts.
  • complete_goal testResults removed — replaced with verificationSummary. The old structured test results interface is gone.

Unified goal + task acceptance

  • Single-dialog confirmationpropose_goal_draft now accepts an optional tasks array parameter. The confirmation dialog shows the goal objective AND the proposed task list together in a single rich TUI view with box-drawing panel (┌─ TASKS ───┐), section headers, and hierarchical indentation for subtasks.
  • Atomic creation — one confirmation (single enter press) creates the goal AND its task list together. No need for separate propose_goal_draft + propose_task_list calls.
  • Backward compatible — existing separate propose_task_list flow continues to work unchanged. Goals without tasks work as before.

Task list & sub-task system

  • Structured task breakdown — the agent can propose a task list via propose_task_list (standalone) or propose_goal_draft with tasks (unified). Both show a Confirm / Continue Chatting dialog. Once confirmed, tasks are displayed in prompts, the widget, serialized to disk, and included in auditor review.
  • Recursive subtasks — tasks can have nested sub-tasks via subtasks?: GoalTask[] (full recursive type). Subtask depth is controlled globally by subtaskDepth in .pi/pi-goal-x-settings.json (default: 1 level). Too-deep subtrees are rejected at proposal.
  • Lightweight subtasks — each task has an optional lightweightSubtasks?: boolean flag. When true, the parent can complete regardless of subtask status. When false/absent (full subtasks), all subtasks must be individually complete before the parent can close.
  • Per-task completioncomplete_task marks individual tasks done with optional evidence/verificationSummary, and skip_task marks tasks as skipped with a required reason. Neither stops the turn, so the agent can continue uninterrupted.
  • Recursive lookupfindTaskInTree and updateTaskInTree search and update tasks at any depth. Subtask IDs are valid targets for complete_task and skip_task.
  • Subtask gate — parent tasks with full subtasks require all sub-items to be completed or skipped before the parent can close, enforced by recursive checkSubtasksComplete.
  • Duplicate ID validationvalidateTaskListProposal recursively checks all task IDs across the entire tree, preventing collisions between parent/subtask or sibling subtasks.
  • Agent workflow guidance — prompts include a [TASK WORKFLOW] section directing agents to use tasks as progress trackers, completing subtasks immediately when work finishes (not batch-marking at the end).
  • Hierarchical display — task lists with subtasks render with indentation in prompts (taskListBlock, goalPrompt, continuationPrompt) and in the TUI widget (recursive count, BFS next-pending).
  • Optional taskList — goals without a task list work exactly as before. The feature is entirely opt-in.
  • Soft complete_goal gate — when blockCompletion: true is set, complete_goal surfaces a warning if pending tasks remain (prompt-level only; the agent can still complete).

Goal objective is immutable

  • The goal objective is immutable — the agent must not modify it autonomously. Objective changes are only possible through propose_goal_tweak, which presents the user with a Confirm / Continue Chatting dialog matching the propose_goal_draft confirmation pattern. This prevents the agent from silently changing the goal contract.
  • propose_goal_tweak is the sole mechanism for updating the objective, available exclusively during a /goal-tweak drafting flow. If the user's requirements change, they must run /goal-tweak to initiate the revision flow.

Deferred archival

  • No more premature archiving: previously, update_goal archived the goal file inline within the tool handler before the agent could see the audit result (or skip notification). Archival is now deferred until turn_end — after the agent has received the audit/skip result in the conversation. The goal remains visible in the active pool through the entire completion flow.
  • Cleaner lifecycle: completed goals are archived by the turn_end lifecycle hook, not by the tool handler. The accountProgress guard skips disk reconciliation for completed goals.

E2e test infrastructure

  • Deterministic fork tests using --mode json: the e2e suite spawns a real pi --fork --mode json session, parses structured tool_execution_start/tool_execution_end JSON events for field-level assertions — no free-text AI output parsing. Uses --append-system-prompt + --tools to force deterministic tool calls.
  • Full coverage: 310 tests total — function-level integration tests, mock-pi handler tests, file-validity checks, real pi --fork --mode json E2E tests, propose_goal_tweak unit/integration/e2e tests, task list policy/round-trip/render tests (including subtasks), and verification contract tests.

Completion auditor

  • Live progress widget — when the auditor runs, the TUI shows a spinner, a progress bar ([████░░░░] 40%), step labels (Inspecting files..., Verifying success criteria...), the current tool being executed, and recent output lines. No more wondering if anything is happening.
  • Per-goal auditor toggle — during goal confirmation, press a to toggle the auditor on/off for that goal. The toggle uses a ●/○ indicator between the goal summary and confirm options. The default position comes from settings; the per-goal override persists within the session.
  • Escape to skip — press Escape during an audit to abort it and complete the goal immediately. The skip is recorded in the ledger as audit_skipped with reason user_aborted and auditor model metadata.
  • Disable the auditor entirely — set disabled: true in .pi/pi-goal-x-settings.json (or toggle it via /goal-settings). The agent can still bypass with user confirmation by passing confirmBypassAuditor: true to complete_goal.
  • Skipped audits are recorded — every skip (whether disabled or Escape-aborted) is logged to the ledger with the reason, provider, model, and thinking level for full traceability.
  • Robust abort detection — the auditor detects aborts both from exceptions and from session.prompt() returning after an abort signal, preventing stuck goals or ghost states.
  • Cleaner lifecycleAbortSignal is properly wired to session.abort(), animation timers are cleaned up, and the unsubscribe path is always executed. No more having to kill the session.
  • Completion report includes full auditor output — the auditor's full report is included in the goal completion conversation message upon approval, not just a verdict.
  • Session factory injectionrunGoalCompletionAuditor accepts an optional createSession parameter for testability, enabling mock auditor sessions in tests.
  • Structured test evidence — the executor can pass testResults (exit code, suite name, output, timestamp) via complete_goal({testResults}). The auditor receives a <test_evidence> block and is instructed to check it before re-running test suites, skipping redundant re-runs.

Drafting & UX

  • Normalized proposal-refinement language — consistent terminology ("keep refining through normal proposal cycles") across all drafting prompts and tools.
  • PI_GOAL_AUTO_CONFIRM=0 opt-out — explicitly set the env var to 0 to disable auto-confirm even in headless contexts (useful for benchmarking).

Testing

  • Comprehensive abort/skip coverage — unit tests for audit_skipped ledger events, disabled auditor config, Esc-to-skip widget behaviour, post-prompt abort detection, and the confirmBypassAuditor parameter.

What it provides

  • Two goal styles: regular goals for open-ended work, and Sisyphus goals for patient ordered execution.
  • Intent-before-run flow: /goals and /sisyphus start a discussion where the agent can clarify, research, and grill before any work begins.
  • Direct set flow: /goals-set and /sisyphus-set immediately create and start a goal from the supplied objective.
  • Confirm-before-commit for discussions: the agent must call propose_goal_draft; the user confirms or keeps chatting.
  • Full goal visibility: after confirmation, the final objective is printed back into the conversation in full.
  • Multiple open goals: .pi/goals/ may hold several active goal files at once; each pi session focuses exactly one goal at a time.
  • Session-local focus: the focused goal id is stored as a branch-local session entry, not in goal markdown metadata.
  • Auto-continue loop: confirmed goals can continue across turns until completion, pause, abort, user interruption, or the empty-turn guard.
  • Schema gates: unsafe lifecycle transitions are rejected by tool validators, not just prompts.
  • Sisyphus as a light variant: Sisyphus shares the normal lifecycle/tools and differs only in prompt style and completion standard.
  • Pause/resume/abort/clear lifecycle: goals can be paused by the user, paused by the agent when blocked, resumed, completed from pause, aborted, or archived.
  • Disk-backed state: active and archived goals are stored under .pi/goals/.
  • Lightweight built-in questionnaire tools: goal_question and goal_questionnaire let the agent ask structured drafting questions without depending on another package.
  • Above-editor status widget: pi shows the current goal, status, progress, and active file path while work is running.

Install

From npm:

pi install npm:pi-goal-x

From a local checkout:

pi install .

Try once without installing:

pi -e .

Quick start

Regular goal

/goals add structured logging to the auth module

Flow:

  1. The agent clarifies, researches, or grills only when the goal contract needs it.
  2. The agent calls propose_goal_draft with a concrete objective once the contract is clear.
  3. pi shows a full plain-text confirmation report.
  4. If confirmed, the full finalized goal is printed into the conversation and written to .pi/goals/.
  5. The new goal becomes this session's focus. Existing open goals remain in .pi/goals/ and can be selected later with /goal-focus.
  6. The agent works only on the focused goal until it calls update_goal(status="complete"), pauses, aborts, produces an empty/non-progress turn, or the user interrupts.

Sisyphus goal

/sisyphus Refactor the auth flow: 1) extract token validation. 2) wire it into login. 3) update tests.

Sisyphus mode is for patient ordered execution. It uses the same lifecycle and tools as a regular goal; the difference is the prompt style and completion standard: preserve the user's order, do not rush, do not invent preflight/reconnaissance steps, and stop to ask when blocked.

If the objective is already final and should start immediately, use:

/goals-set add structured logging to the auth module
/sisyphus-set Refactor auth flow exactly as ordered: 1) extract token validation. 2) wire it into login. 3) update tests.

User commands

/goals <topic>          Discuss/research/grill a regular goal, then confirm a draft
/sisyphus <topic>       Discuss/grill a Sisyphus-style goal, then confirm a draft
/goals-set <objective>  Immediately create and start a regular goal
/sisyphus-set <objective> Immediately create and start a Sisyphus-style goal
/goal-status            Show focused goal state
/goal-list              List all open goals in .pi/goals/
/goal-focus             Choose this session's focused goal
/goal-tweak <change>    Draft a revision to the focused active/paused goal
/goal-pause             Pause the focused active goal
/goal-resume            Resume a paused goal
/goal-settings          Configure pi-goal settings, including auditor model settings
/goal-abort             Abort/archive the focused goal or cancel drafting
/goal-clear             Archive the focused goal or cancel drafting

Pressing Esc or aborting an active run pauses the goal so it does not remain falsely active.

Multiple open goals and focus

pi-goal separates durable goals from session focus:

  • Goal pool: every open goal is an active_goal_*.md file under .pi/goals/.
  • Focused goal: the current pi session has one focused goal id stored in a pi-goal-focus custom session entry.
  • No focus in markdown: goal files describe the goal itself; they do not record which session is focused on them.
  • Branch-local focus: because focus is reconstructed from the current session branch, /tree navigation can restore a different focus for a different branch.
  • One continuation chain: auto-continue only schedules work for the focused goal in the current session.

Creating a goal with /goals, /sisyphus, /goals-set, or /sisyphus-set no longer clears other open goals. It creates a new active goal file and focuses it. Use /goal-list to inspect open goals and /goal-focus to switch the session focus. If the latest focus entry explicitly clears focus, or points at a missing/stale goal, a remaining single open goal is not auto-focused; single-open auto-focus only happens when no focus entry exists at all. If multiple open goals exist and the session has no valid focus, /goal-resume, /goal-clear, /goal-abort, /goal-pause, and /goal-tweak ask the user to choose a goal instead of acting on all of them.

Agent tools

The extension exposes tools only when they make sense for the current lifecycle phase.

Tool Visible when Purpose
goal_question drafting / tweak drafting Ask one focused user question
goal_questionnaire drafting / tweak drafting Ask multiple structured questions
get_goal always Read the focused goal state; mentions other open goals when present
propose_goal_draft drafting only (goal creation) Submit a concrete draft for user confirmation
propose_goal_tweak tweak drafting only Submit a revision to an existing goal (shows Confirm / Continue Chatting dialog)
complete_goal focused active or paused goal Mark the focused goal complete — supply a verificationSummary covering all contract items. When the auditor is disabled, supply confirmBypassAuditor: true after user confirmation to bypass the audit
pause_goal focused active goal Pause the focused goal because of a real blocker
abort_goal focused active or paused goal Abort/archive an obsolete, impossible, unsafe, or user-cancelled focused goal
propose_task_list active or paused goal Propose a structured task list for user confirmation (stops the turn)
complete_task active or paused goal Mark a task complete with optional verificationSummary. If the task has a verificationContract, the summary is required (does not stop turn)
skip_task active or paused goal Mark a task skipped with a required reason (does not stop turn)
propose_goal_tweak tweak drafting only Submit a revision to the focused goal (shows Confirm / Continue Chatting dialog)
step_complete hidden / legacy Compatibility no-op; Sisyphus no longer requires a step counter
create_goal hidden Direct calls are rejected; normal creation goes through propose_goal_draft

Drafting behavior

/goals and /sisyphus start a lightweight intent discussion, not a heavy runtime sub-state. The agent clarifies, researches, and grills only when needed, may proceed directly for fully specified requests, and then calls propose_goal_draft to show the user a Confirm / Continue Chatting dialog. goal_question and goal_questionnaire are available when structured input helps, but plain conversation is acceptable.

/goals-set and /sisyphus-set skip the discussion and confirmation dialog. They directly create and focus an active goal from the supplied objective so execution can begin immediately.

The agent may do minimal read-only reconnaissance when it directly improves the goal contract, but should not begin substantive implementation before confirmation. The strict runtime starts after the user confirms the draft and an active goal is created.

When a draft is proposed, the confirmation UI shows a full plain-text report with draft details, the original topic, and the proposed goal. If the confirmation UI throws in interactive mode, creation fails closed and confirmation remains active; it never auto-creates a goal. When a draft is confirmed, the tool result includes the full final objective, not a one-line summary, and normal work tools (write, read, bash, edit) are available for execution. This makes the confirmed contract visible in the conversation as well as on disk.

While goal confirmation or tweak drafting is active, old goal execution is suspended: active-goal prompts, accounting, and auto-continue checkpoints do not run for the previously focused goal.

Completion behavior

Completion is also explicit and is checked by an independent pi auditor agent. The executor calls update_goal with its completion claim:

{
  "status": "complete",
  "completionSummary": "What was completed and what evidence proves it."
}

Before archiving the goal, update_goal starts a separate pi agent in an isolated in-memory session. The auditor receives the objective, the executor's completion claim, and current goal metadata, then can inspect the workspace with read-only-oriented tools (read, grep, find, ls, and bash). It must end its report with exactly one marker:

  • <approved/> archives the goal as complete.
  • <disapproved/>, no marker, an error, or an abort rejects completion and leaves the goal open.

The auditor is semantic, not a paperwork checklist: it should reject scaffold-only, alpha, generated-template, proxy-metric, build-only, or weakly verified completions when the real user outcome is not satisfied.

By default the auditor uses the current/default pi model. Configure it via .pi/pi-goal-x-settings.json, or interactively with /goal-settings (see Configuration).

The completion result prints a full report into the conversation:

  • Goal complete.
  • optional completion summary / evidence supplied by the executor
  • the auditor's approval report
  • full current goal details, including objective, status, usage, mode, and file path

Sisyphus goals use the same completion tool as regular goals. The stricter part is the prompt/criteria standard: the agent should only call completion after the whole ordered objective is actually satisfied and likely to survive independent auditing. A paused goal can also be completed directly when the agent already has enough evidence that every requirement is satisfied; it does not need a resume just to call complete_goal.

Schema gates

The shipped gates are intentionally small and mechanical.

Gate Prevents
Focus consistency /goals accidentally becoming Sisyphus, or /sisyphus becoming regular mode
Confirm-before-commit The agent silently creating or replacing a discussion-based goal
Direct set intent /goals-set and /sisyphus-set are explicit user shortcuts that bypass draft confirmation
Completion auditor gate Archiving completion unless an independent pi auditor agent returns <approved/>
Abort gate Aborting missing, stale, completed, or reasonless goals
Direct-create rejection Hidden create_goal calls creating goals without the confirmation flow
Post-stop block Continuing to call tools after pause_goal, abort_goal, complete_goal, or propose_goal_tweak stops the turn
Empty-turn guard Pure chat loops that would keep auto-continuing without meaningful goal work
Abort pause Active goals staying active after user abort / Ctrl-C
Disk reconciliation External pause/archive/delete/status changes being ignored or overwritten by stale memory
Post-compaction reminder Losing the active objective after session compaction

Files

.pi/goals/active_goal_<timestamp>_<id>.md
.pi/goals/archived/goal_<timestamp>_<id>.md

Multiple active_goal_*.md files may exist simultaneously. This is the project-level open goal pool. The selected/focused goal is intentionally not stored in these files; focus lives in session custom state.

Each file contains:

  1. extension-owned JSON metadata;
  2. a user-editable # Goal Prompt section;
  3. progress/status information.

Before commands, tools, and lifecycle hooks act on a focused goal, the runtime reconciles the focused record against the active goal file on disk. External archive/delete/status changes therefore win over stale in-memory state and cannot resurrect deleted active files. Prompt-body edits are still picked up from the # Goal Prompt section; focus is never stored in goal markdown.

Goal paths are constrained to .pi/goals/ and .pi/goals/archived/; absolute paths, traversal, NUL bytes, symlinks, and unsafe metadata paths are rejected.

Configuration

All settings live in a single file: .pi/pi-goal-x-settings.json

Configured interactively via /goal-settings, or edited directly:

{
  "disableTasks": false,
  "disableContracts": false,
  "subtaskDepth": 1,
  "provider": "fireworks",
  "model": "accounts/fireworks/models/deepseek-v4-flash",
  "thinkingLevel": "high",
  "disabled": false
}
Field Default Purpose
disableTasks false Suppress task list features entirely when true
disableContracts false Suppress verification contract enforcement when true
subtaskDepth 1 Maximum nesting depth for subtasks
provider system default Provider name for the auditor agent
model system default Model name for the auditor agent
thinkingLevel system default Thinking level: off, minimal, low, medium, high, xhigh
disabled false When true, skip the completion audit entirely

Env var overrides:

  • PI_GOAL_DISABLE_TASKS=1 — disable task features (takes precedence over file)
  • PI_GOAL_DISABLE_CONTRACTS=1 — disable contract enforcement (takes precedence over file)
  • PI_GOAL_SETTINGS_FILE=custom-path.json — alternative settings file path (relative to cwd or absolute)

Environment variables

Variable Default Purpose
PI_GOAL_AUTO_CONFIRM unset When 1, auto-confirms drafts in headless/test contexts
PI_GOAL_DISABLE_TASKS When 1, disable task features (overrides settings file)
PI_GOAL_DISABLE_CONTRACTS When 1, disable contract enforcement (overrides settings file)
PI_GOAL_SETTINGS_FILE .pi/pi-goal-x-settings.json Alternative settings file path (relative to cwd or absolute)

Development

npm install
npm test
npm run check
npm pack --dry-run

The fast unit suite uses Node's built-in test runner and covers core parsing, drafting gates, lifecycle policy, abort policy, questionnaire formatting, centralized tool names, Sisyphus prompt-style behavior, completion reporting, and display helpers.

The experiment harness under experiments/ runs full pi sessions against real model calls and mechanical rubrics.

cd experiments
bash harness/run.sh C1-vague-goal-set --count 3 --grade --no-smoke

Package contents

The npm package ships only the runtime extension, docs, and package metadata. The extension is split into small modules:

extensions/goal.ts                 orchestration, commands, tools, events, timers
extensions/goal-record.ts          goal record types, normalization, creation helpers
extensions/goal-pool.ts            open-goal pool, focus resolution, list/selector text helpers
extensions/goal-core.ts            display helpers
extensions/goal-draft.ts           lightweight confirmation prompt, proposal validation, drafting tool gate
extensions/goal-policy.ts          lifecycle, pause/resume/complete, and Sisyphus policy
extensions/goal-auditor.ts         independent pi auditor agent for completion approval, config, and progress tracking
extensions/goal-ledger.ts         event append, read, validation, sanitization, and reconstruction
extensions/goal-questionnaire.ts   built-in question UI and question tool registration
extensions/goal-tool-names.ts      centralized published tool names and allowlists
extensions/prompts/goal-prompts.ts active, continuation, tweak, and stale prompts
extensions/storage/goal-files.ts   goal file paths, serialization, parsing, archive IO
extensions/widgets/goal-widget.ts  above-editor goal beacon component
extensions/widgets/goal-notifications.ts widget-style notification text

Design principles

  • User owns intent: only the user starts, replaces, resumes, clears, or confirms goals; the agent may only pause, complete, or abort through schema-gated lifecycle tools with evidence/reason.
  • One commit path: normal goal creation goes through drafting and confirmation.
  • Schema beats prompt walls: recurring failure modes are handled by validators and tool-call interceptors.
  • Visible contracts: confirmed goals and completion reports are printed fully into the conversation.
  • Lifecycle-shaped tool surface: the agent sees only tools appropriate to the current phase.
  • Disk-backed continuity: goal state survives context churn and can be audited from .pi/goals/.
  • Human-owned focus: the agent may work on the focused goal, but only user commands/UI selection switch focus.

Upstream

This repository is a downstream fork of @capyup/pi-goal. To sync with upstream changes:

git fetch upstream
git merge upstream/main
# resolve conflicts, test, commit

The upstream remote should point to https://github.com/capyup/pi-goal.git.

Release policy

This repository can be validated locally with tests and packaging checks. Publishing a new npm version, pushing tags, and running pi update are explicit release steps and are not part of ordinary implementation goals unless requested.

License

MIT