npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ggbondex/pi-goal

v0.3.0

Published

Autonomous goal loop for pi: an AI judge decides whether the goal is done, otherwise the original goal is re-sent to the agent.

Readme

goal-loop

自主目标循环扩展:给 pi 一个目标,它停下来时由 AI 判定目标是否真的完成;没完成就把目标再发一遍,直到完成、受阻、或达到续跑上限。

为什么

pi 做完一个小项就会停下来问"要不要继续"。跑长计划(例如 docs/IMPLEMENTATION_PLAN.md 的 29 个切片)时得一直盯着回车。 这个扩展把"要不要继续"的判断交给一个判定模型,而不是交给人。

用法

/goal 按 docs/IMPLEMENTATION_PLAN.md 从当前进度顺序完成,直到所有切片的判定都跑通过

只想给个目标、直接开跑(不规划):

/goal <目标>

想先让 pi 把目标想清楚、写成一份计划再开跑:

/goal plan 给助手加记笔记能力
/goal plan 完成 docs/IMPLEMENTATION_PLAN.md
/goal plan @docs/IMPLEMENTATION_PLAN.md        # 显式指定计划文件(只读引用)

之后:

/goal                 查看状态
/goal plan            用法
/goal stop            停止循环(保留目标,可 resume)
/goal resume          从断点接着跑
/goal clear           彻底清除目标(不再记忆,含重启/切分支后)
/goal model <spec>    指定判定/规划模型:auto | provider/modelId | modelId
/goal max <n>         续跑上限(默认 15)
/goal help            用法

一次性默认值可用环境变量:PI_GOAL_MAX、PI_GOAL_MODEL、PI_GOAL_RETRY_BASE_MS(错误冷却退避基数,默认 60s)、PI_GOAL_JUDGE_TIMEOUT_MS(判定调用超时,默认 90s)。

每一轮发生什么

  1. /goal <目标> 把目标当作普通用户消息发出,agent 开始干活。
  2. 当这轮 agent 真正要收尾时(agent_before_settle),扩展把目标 + 当前对话记录交给判定模型,要求它只返回一个 JSON: {"done": bool, "blocked": bool, "reason": "...", "next": "..."}。
  3. 判定为 done → 停止,并提示"目标已完成"。 blocked → 暂停(不是结束):把"需要你决定什么"告诉你;你直接回答即可,下一轮会自动恢复并接着跑。想彻底停下用 /goal stop。 都不是 → 注入一条续跑消息(含判定原因、下一步、以及原始目标原文),agent 继续。
  4. 瞬时错误自愈:provider 错误(429 限流、超时、掉线——用 pi 内置重试同一套判定)不会让循环静默停摆:扩展在收尾边界内退避冷却(60s 起指数、5min 封顶),最多自动重试 5 次(约 17 分钟),每次把失败那轮从上下文抠掉再续跑。预算烧完或错误非瞬时 → 暂停:状态行显示「运行出错 · 等你答复」,你直接回话即自动恢复。判定调用有 90s 超时;判定失败也走同样的冷却重试,连续 3 次才停。
  5. 硬上限保护:最多自动续跑 max 次;你在判定或干活时按 Esc 会直接停止循环。

判定提示词里专门写明:agent 问"要不要继续"不算完成、也不算受阻——这正是要修的行为。

计划(/goal plan,可选)

规划是可选的一段开场,不是一种模式:只有显式敲 /goal plan 才走它,普通 /goal 一个字不变。

它只做一件事:让 pi 先把计划写好。

/goal plan <意图|@文件> 让 pi 先调研仓库(读合同、读测试、看真实存在哪些命令),然后把计划写成一份人读的文件 —— 插件自己的 .pi/goal-plans/<slug>.md,头两行是两个字段:

目标:<终态,一句话>
出口:<证明做到的准确命令>

下面是正文:路线(按依赖排序的各个阶段,每个写清做什么、动哪些文件、它自己的验收命令)、已经定下的决定、看得见风险,以及一节「未定项」。规划就是一次普通的 pi turn,不限制工具,只在提示词里要求「先别动手实现,这一步只出计划」。

计划是路线图,不是账本。 插件不跟踪任何里程碑状态,也不数「完成了几片」:进度只有「第 n/15 轮」和上次判定的原因。这是刻意的取舍 —— 计划一旦成了完成判据,当初多写的一条就会让目标永远完不成;而且账本要准就得配一整套规则(按区间认领、片不能改名、判定要回答"认到哪一片"……),那些规则本身就长出了好几个 bug。计划可以随认知更新,agent 也可以改它。

写完之后:打印目标、出口、文件路径和开头十几行,等你确认。你回一句「同意」就开始跑 —— 不需要再敲一次 /goal plan,扩展用 input 事件接住那句普通回复(同意 / 取消 / 任何修改意见,后者会带上去重新规划)。确认后起的是一个普通 goal:判定模型对「目标 + 出口」判完成与否,循环把它迭代到完成为止。

  • 信息不够就先问:如果 pi 判断不问你没法写出忠实的计划,它不写文件,直接在回复里问;这句话会被显眼地摆出来等你回答,然后它带着答案重新规划。连问三轮还写不出文件就停下报错,不空转。
  • 没有「目标」字段的文件不算计划:会被当成"它问了什么",而不是当成一份空计划 —— 判据只有一条。
  • 不动你的文件:你 @ 的那份只做只读引用。
  • 规划失败(读不到文件 / 出错 / 中断)不启动,直接告诉你。

设计上的取舍

  • 判定基于证据:要求 transcript 里有实证(文件改动、命令输出、测试结果)。目标里写清验收标准,判定会准得多。
  • 默认跟随会话模型:判定调用用的是当前会话模型;想省钱可以在 /goal model 里换成便宜模型。
  • 只读 transcript 尾部 40k 字符:目标很长时前面的上下文可能被截断,所以续跑消息里每次都重申原始目标。
  • 状态存在会话里:以 custom 条目写进 transcript,不落额外文件、不发网络、不起进程。分支/恢复时状态自动正确。
  • 不干预无目标会话:没有活动目标时,扩展在所有事件上都是空操作。

结构

  • index.ts — 循环接线与命令(单文件)
  • plan.ts — 计划模块:规划提示词、读回计划文件的两个字段、预览、交接、确认分类(纯函数,只有读文件有副作用)
  • 依赖:只 import pi 自带供给的包(@earendil-works/pi-ai、@earendil-works/pi-coding-agent、@earendil-works/pi-tui)+ node:fs

安装

作为 pi 包装(推荐):

pi install npm:@ggbondex/pi-goal
# 或直接装 GitHub 上的源码:
pi install git:github.com:ggbondex/pi-goal

或手动放到用户级扩展目录(所有项目生效):

ln -s "$PWD" ~/.pi/agent/extensions/goal-loop

改完在 pi 里执行 /reload。

测试

npm test          # 先 test/setup.mjs 复用本机已装的 pi,再跑两个测试
  • test/mock.test.mjs — 用假 model registry 覆盖各分支(启动 / 续跑 / 完成 / 受阻 / 中断 / 上限 / 恢复 / 判定失败 / 停止 / 状态行 / 规划→确认→驱动→完成),不发网络、不花钱。
  • test/plan.test.mjs — plan.ts 的纯函数(字段解析 / 预览 / 交接 / 确认分类 / 文件路径 / 提示词)。
  • test/integration.test.mjs — 在真实 pi 运行时里用假 provider 跑完整循环,验证续跑消息确实被下一轮看到。

test/setup.mjs 只是把本机已安装的 pi 包软链进 node_modules/,不下载任何东西;已存在的真实安装不会被覆盖。