geto-goals
Durable autonomous goal loop for pi (Codex /goal style). /goal set|show|edit|pause|resume|clear plus a goal_report tool and an agent_settled continuation loop. Goal state lives in .pi/goals/goal.json and is re-injected every turn, so it survives compactio
Package details
Install geto-goals from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:geto-goals- Package
geto-goals- Version
0.3.0- Published
- Aug 14, 2026
- Downloads
- 273/mo · 273/wk
- Author
- mr-jones123
- License
- MIT
- Types
- extension
- Size
- 28.9 KB
- Dependencies
- 2 dependencies · 1 peer
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
geto-goals
Durable autonomous goal loop for pi — Codex /goal style.
Install
pi install npm:geto-goals
# or from this repo:
mkdir -p ~/.pi/agent/extensions/geto-goals
ln -s "$PWD/packages/geto-goals/index.ts" ~/.pi/agent/extensions/geto-goals/index.ts
Then /reload in pi.
Commands
/goal <text> [--done <criteria>] [--max-iterations N] [--budget $]
/goal set|show|edit <text>|pause|resume|clear|status
Example:
/goal Migrate the API client to v3; update all call sites; run unit and integration
tests; keep going until they pass. --done "all tests green" --max-iterations 30
/goal <free text> (or /goal set <text>) starts the goal and immediately kicks off the agent — Codex /goal style. Subcommands: show/status, edit, pause, resume, clear.
Tool
goal_report(status: "progress"|"done"|"blocked", note) — the agent's progress channel. Writing it updates the durable goal file; the loop continues while the goal is active. The injected prompt instructs the agent to call it with done only after a requirement-by-requirement completion audit passes, and blocked only after the same blocker repeats across three consecutive goal turns.
The loop
before_agent_startinjects the goal (text, definition of done, last/next step, recent progress, iteration/budget counts) into every turn's system prompt, wrapped as untrusted user data.agent_endqueues a continuation (a customgoal-continuationmessage — not a user message, so it never re-enters the run lifecycle) while the goal is active and guards allow:- iteration cap (
--max-iterations, default 50) - cost budget (
--budget $, summed from session usage) - stuck detection (two identical progress reports in a row)
- iteration cap (
- A
contextfilter keeps only the latest continuation in the LLM context and strips goal UI cards, so long autonomous runs do not bloat the transcript. - Aborted runs ask whether to pause (auto-pause headless) instead of blindly continuing — this is what prevents the runaway abort loop.
- Assistant
errorruns stop automatic continuation and mark the goalusageLimitedorblocked;/goal resumerestarts it. session_compactre-appends the goal state to the transcript; the goal itself lives in the file, so summaries cannot lose it.- explicit
done/blockedviagoal_report
- explicit
session_compactre-appends the goal state to the transcript and resumes the loop.
Why it survives compaction
The goal is state, not context: it lives in <project>/.pi/goals/goal.json. Compaction can only delete context; it cannot touch the file. Every turn re-injects the goal verbatim from the file, so no matter how much history is summarized, the agent always sees the full goal and where it left off (lastStep/nextStep). The transcript mirrors (custom entries + goal_report results) are for humans only.
The loop also survives /new and restarts — the file is per-project, and agent_settled restarts it on any session in the project.
Releases
Versions, changelogs, tags, and npm publication are managed by Release Please from Conventional Commits. Do not edit the package version manually.
Notes
- Subagents spawned by geto-subagents run with
GETO_GOALS_DISABLED=1and are excluded from the loop. - Pairs well with geto-subagents: the goal loop can delegate bounded chunks to fork-based subagents, which report back.