@fyeeme/pi-goal 1.0.0
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.
- package/CHANGELOG.md +43 -0
- package/LICENSE +21 -0
- package/README.md +59 -0
- package/index.ts +651 -0
- package/package.json +65 -0
- package/src/commands.ts +325 -0
- package/src/evaluator.ts +218 -0
- package/src/format.ts +35 -0
- package/src/prompts/evaluator-complete.md +26 -0
- package/src/prompts/evaluator-impossible.md +20 -0
- package/src/prompts/goal-budget-limit.md +15 -0
- package/src/prompts/goal-continuation.md +30 -0
- package/src/prompts/goal-mode-active.md +23 -0
- package/src/prompts/goal-mode-context.md +4 -0
- package/src/prompts/goal-todo-context.md +12 -0
- package/src/prompts/goal.md +11 -0
- package/src/prompts/guided-goal-interview.md +37 -0
- package/src/restore.ts +92 -0
- package/src/runtime.ts +565 -0
- package/src/state.ts +124 -0
- package/src/template.ts +154 -0
- package/src/todo-bridge.ts +136 -0
- package/src/tool.ts +557 -0
- package/test/evaluator.test.ts +186 -0
- package/test/index.test.ts +557 -0
- package/test/omp-alignment.test.ts +975 -0
- package/test/runtime.test.ts +471 -0
- package/test/template.test.ts +89 -0
- package/test/tool.test.ts +528 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [Unreleased]
|
|
4
|
+
|
|
5
|
+
## [1.0.0] - 2026-09-09
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Initial release: oh-my-pi goal mode ported to a pi extension.
|
|
10
|
+
- `goal` tool (`create`/`get`/`complete`/`resume`/`drop`/`impossible`) with omp's exact operation semantics, registered at load and kept out of the active toolset until goal mode or a guided interview needs it.
|
|
11
|
+
- **Independent completion/impossibility evaluator** (`src/evaluator.ts` + `evaluator-complete.md` / `evaluator-impossible.md`), absorbed from Claude Code 2.1.261's goal design (bin/claude.exe, 2026-09-07) and going one step further than CC:
|
|
12
|
+
- `goal({op:"complete"})` requires `evidence` — the agent's per-deliverable audit of the current repo state — and is gated by an independent evaluator: a fresh `pi -p --no-session` subprocess (spawn resolution ported from pi-subagents' `getPiInvocation`) that re-verifies the repository itself (runs the checks; grounded, where CC's evaluator is transcript-only). Its JSON contract follows CC's: `{ok, reason}` with evidence quoting and the default direction "insufficient evidence = NOT met". A refuted claim keeps the goal active, returns the evaluator's findings in the tool result, and forbids re-claiming with the same evidence; omp's complete error semantics (no goal / already complete / dropped) are preserved before any evaluator spend. Evaluator unavailability (spawn failure, ~5 min timeout, unparseable/out-of-contract output) falls back to the omp self-audit completion, honestly labeled (`unavailable-fallback`); caller aborts rethrow.
|
|
13
|
+
- New `goal({op:"impossible", reason})` op — CC's third verdict channel with its "the claim is evidence, not proof — independently confirm" rule: the evaluator adjudicates the impossibility claim; confirmation pauses the goal (`state.reason: "impossible-confirmed"`) with the tool result instructing an honest report to the user; refutation keeps it working; after 2 unconfirmed disputes (`Goal.impossibleReports`, persisted) the goal pauses for a human decision (`"impossible-disputed"`). An unadjudicated claim (evaluator unavailable) changes no state and routes to the user.
|
|
14
|
+
- Tool details gain `evaluator: {verdict, reason}` (`confirmed` / `rejected` / `unavailable-fallback` / `impossible-confirmed` / `impossible-refuted` / `impossible-disputed` / `unavailable`), rendered as an evaluator line in the tool result.
|
|
15
|
+
- `pauseGoal` accepts an explicit `reason`; `recordImpossibleReport` bumps + persists the dispute counter; `isGoal` accepts the optional `impossibleReports` field (old snapshots restore unchanged).
|
|
16
|
+
- `GoalRuntime` with omp's budget accounting verbatim: token deltas include cache writes and exclude cache reads, wall-clock seconds advance in whole persisted steps, budget-limit steering fires once per goal id, interrupts pause, cold resume auto-pauses, tree navigation preserves.
|
|
17
|
+
- Autonomous continuation loop with no-tool-call suppression and user-message re-arm.
|
|
18
|
+
- `/goal` (`set`/`show`/`pause`/`resume`/`drop`/`budget`) with interactive menu, and `/guided-goal` interview kickoff.
|
|
19
|
+
- Session persistence via `goal-state` / `goal-cleared` / `goal-completed` custom entries with branch-aware restore.
|
|
20
|
+
- pi-todo integration: live `<todo_context>` block inside the goal context message.
|
|
21
|
+
- `goal_updated` event bus broadcast for other extensions; footer status segment.
|
|
22
|
+
- `ui_prompt_start`/`ui_prompt_end` integration: continuation turns are withheld while a blocking dialog is open and resume when it closes while idle.
|
|
23
|
+
- `agent_settled` status refresh, `/goal` argument autocomplete (`getArgumentCompletions`), multi-line objective editor, and a persistent `goal-completed` entry renderer (all per docs/extensions.md v0.84.4).
|
|
24
|
+
- `test/omp-alignment.test.ts`: 47-test alignment suite pinning pi-goal's commands, status segment, renderer strings, persistence, and escaping to omp sources verbatim.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- `goal` tool `op` parameter uses `StringEnum` instead of `Type.Union`/`Type.Literal` for Google API compatibility (docs/extensions.md, Custom Tools).
|
|
29
|
+
- Peer dependencies now require pi 0.84.4+ (`ui_prompt_start`/`ui_prompt_end` events).
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
|
|
33
|
+
- omp alignment pass (test + fix until behavior is identical to oh-my-pi goal mode):
|
|
34
|
+
- `escapeXmlText` escapes only the `& < >` trio; quotes now stay verbatim in goal prompts, matching omp `sanitize-text.ts` (omp's goal-runtime tests pin this).
|
|
35
|
+
- `/goal <objective>` while a goal is active now reports omp's status message instead of opening the menu; while paused it warns "Resume the current goal first...".
|
|
36
|
+
- Dropping a goal now clears session state entirely (omp `commitState(undefined)`): `/goal show`, `/goal resume`, the menu, and `/guided-goal` treat a dropped goal like no goal, and a new `/goal <objective>` starts fresh.
|
|
37
|
+
- Menu item label is omp's `Adjust budget…` (ellipsis); the budget prompt is an editor prefilled with the current budget (omp `#promptGoalBudgetEdit`).
|
|
38
|
+
- Notification severities mirror omp: `showStatus` → info, `showWarning` → warning, `showError` → error (e.g. invalid budget input renders as an error).
|
|
39
|
+
- Footer status segment reworked to omp `renderGoalMode`: `<icon> Goal <used>[/<budget>]` with the omp unicode icon set (🎯/⏸/⚠), visible only while enabled or paused; the pi-specific `waiting for user` suffix was removed.
|
|
40
|
+
- Goal tool renderer strings match omp: call `⏳ Goal: set "…" · budget 5K`, result `◎ Goal: set ⟦active⟧` (⟦⟧ badge brackets, `goalBadgeColor`), error `✘ Goal: <op>` + two-space detail, no-goal `⚠ Goal: <op> · no active goal`; objective caps at omp TRUNCATE_LENGTHS (60 call / 100 result).
|
|
41
|
+
- `/goal` description is omp's "Toggle goal mode (persistent autonomous objective for this session)"; argument completions mirror omp `buildArgumentCompletions` (trailing-space values, null past the subcommand word).
|
|
42
|
+
- `/guided-goal` no longer emits a kickoff status message (omp shows none); `/goal resume` guard requires an actually-paused goal.
|
|
43
|
+
- `/guided-goal` kickoff queues as a follow-up behind an in-flight run (omp `session.followUp`), never a steer.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 fyeeme
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# pi-goal
|
|
2
|
+
|
|
3
|
+
oh-my-pi's **goal mode** migrated to a [pi](https://github.com/earendil-works/pi-coding-agent) extension: one persistent autonomous objective looped until the agent can *prove* the success criteria — not until it runs out of things to say.
|
|
4
|
+
|
|
5
|
+
Source: [oh-my-pi](https://github.com/can1357/oh-my-pi) (a fork of badlogic/pi-mono), `packages/coding-agent/src/goals` + the goal wiring in its agent session and interactive mode. The runtime semantics are ported behavior-for-behavior; host-internal surfaces are mapped to pi's extension API (see the adaptation table in `index.ts`). One deliberate deviation, absorbed from Claude Code 2.1.261's goal design (binary-verified 2026-09-07): **completion is gated by an independent evaluator** instead of self-graded — see below.
|
|
6
|
+
|
|
7
|
+
## What it does
|
|
8
|
+
|
|
9
|
+
- **`goal` tool** — `create` / `get` / `complete` / `resume` / `impossible` / `drop`. Creating a goal enables goal mode; completing it requires verified evidence of every deliverable (see the evaluator gate below); the runtime refuses double-completes.
|
|
10
|
+
- **Independent evaluator gate (CC 2.1.261 absorption)** — `goal({op:"complete", evidence})` passes the agent's per-deliverable audit to a fresh `pi -p` subprocess that re-verifies the repository itself (it can run the tests — grounded, unlike CC's transcript-only evaluator). Its JSON contract defaults to *insufficient evidence = not met*. A refuted claim keeps the goal active and returns the evaluator's findings; the tool result tells the model to fix the gaps and re-claim with stronger evidence. If the evaluator subprocess cannot run (spawn failure, timeout ≈ 5 min, unparseable output), completion falls back to the omp self-audit behavior, honestly labeled in the result.
|
|
11
|
+
- **`impossible` channel (CC 2.1.261 absorption)** — when the agent believes the goal genuinely cannot be achieved this session, `goal({op:"impossible", reason})` sends the claim to the evaluator, which independently confirms or refutes it ("the claim is evidence, not proof"). Confirmed → the goal pauses (`reason: impossible-confirmed`) and the model must report honestly to the user. Refuted → keep working; after 2 unconfirmed disputes the goal pauses for a human decision (`reason: impossible-disputed`). An unadjudicated claim (evaluator unavailable) changes nothing.
|
|
12
|
+
- **Autonomous continuation** — when the agent yields while the goal is still active, pi-goal re-submits a hidden continuation prompt that restates the objective and the verification checklist, so work continues across turns without user nudges. A continuation turn that produced no tool calls suppresses the next one (no infinite idle loops); a real user message re-arms the loop. While a blocking dialog is open (`/goal` menus, confirmations, or any extension's `ask_user`), continuations are withheld via `ui_prompt_start`/`ui_prompt_end` and resume when the dialog closes.
|
|
13
|
+
- **Budget accounting** — optional `token_budget` per goal. pi-goal counts input + output + cache writes (cache reads are reused prefix, not new work) plus wall-clock seconds. Crossing the budget flips the goal to `budget-limited` and steers the agent once with a wrap-up instruction. Budget exhaustion is explicitly *not* completion.
|
|
14
|
+
- **Interrupt safety** — Esc interrupts pause the goal (never complete it); usage accumulated so far is kept. Resuming a session auto-pauses a still-active goal, since the run that owned it is gone.
|
|
15
|
+
- **`/goal` command** — `set <objective>`, `show`, `pause`, `resume`, `drop`, `budget <N|off>`, or an interactive menu when called without arguments. Typing an objective while a goal is active (or paused) is rejected with omp's status/warning; `/goal drop` and the menu's Drop confirm before discarding.
|
|
16
|
+
- **`/guided-goal [rough objective]`** — the agent interviews you in normal chat (success criteria, verification method, attempt cap, scope boundaries, stop conditions) and then creates the goal itself via `goal create`.
|
|
17
|
+
- **Footer status** — a `<icon> Goal <used/budget>` segment (omp `renderGoalMode` unicode icon set: 🎯 active, ⏸ paused, ⚠ budget-limited) while the goal is enabled or paused. Completed goals stay visible in the transcript after reloads via a persistent `goal-completed` entry renderer.
|
|
18
|
+
- **pi-todo integration** — when [pi-todo](../pi-todo) is installed, the goal context message includes a live `<todo_context>` block so continuations treat todos as current state, not stale transcript decoration.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pi install npm:@fyeeme/pi-goal
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
or copy/link this directory into `~/.pi/agent/extensions/` (global) or `.pi/extensions/` (project).
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
/goal Ship the parser rewrite with all tests passing # start working
|
|
32
|
+
/goal show # objective, status, tokens, time
|
|
33
|
+
/goal budget 200000 # cap the spend
|
|
34
|
+
/goal pause # ... later ... /goal resume
|
|
35
|
+
/goal drop
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Status line: a `<icon> Goal <used/budget>` segment appears in the footer while a goal is enabled or paused (omp footer segment semantics).
|
|
39
|
+
|
|
40
|
+
## Session persistence
|
|
41
|
+
|
|
42
|
+
Every transition writes a full snapshot entry (`goal-state`, `goal-cleared`, `goal-completed`) to the session. Restore scans the current branch backward, so forks and tree navigation restore branch-local state. Usage totals are derived from the session's own message entries — they survive compaction.
|
|
43
|
+
|
|
44
|
+
## Integration contract for other extensions
|
|
45
|
+
|
|
46
|
+
- Emits `goal_updated` on the shared extension event bus (`pi.events`) after every runtime transition: `{ goal: Goal | null, state: GoalModeState | undefined }`.
|
|
47
|
+
- Reads `todo_updated` events and `todo-phases` entries from pi-todo (works without pi-todo installed).
|
|
48
|
+
|
|
49
|
+
## Development
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm install --ignore-scripts
|
|
53
|
+
npm test # vitest, 118 tests
|
|
54
|
+
npm run typecheck
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## License
|
|
58
|
+
|
|
59
|
+
MIT
|