mcpField
G
gm-skill

gm-skill

github.com/anentrypointAgent 工作流270 次安装4 周前更新
代码仓库

关于 gm-skill

该技能要求 Agent 遵循由 plugkit 管理的有状态工作流程,明确阶段转换并检查完成条件。它还规定通过 spool 动词执行搜索、代码运行、浏览器操作和 git 操作。

主要功能

  1. 01PLAN 到 COMPLETE 的阶段流程
  2. 02按 instruction 派发工具调用
  3. 03完成条件与待办门控
  4. 04基于 spool 的搜索和执行
  5. 05客户端编辑的浏览器见证
  6. 06专用 git 操作动词

适用场景

  1. 01按完成门控推进工作
  2. 02处理待解决的 PRD 项
  3. 03在浏览器中验证客户端编辑
  4. 04通过 spool 管理搜索和 git 操作

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/anentrypoint/gm-skill --skill gm-skill

安装后在 Claude Code 中输入/gm-skill确认已加载。

详细介绍

gm

未调用工具而结束的一轮就是停止;在链条中途停止是最严重的失败。 Agent 只读取工具调用及其输出,因此只包含文字的一轮会结束会话。只要链条仍在进行中(phase != COMPLETE OR prd_pending_count > 0),每一轮都必须以能推进链条的工具调用结束(instruction、文字中提到的下一个动词,或 transition)。不要总结,不要说“这是我做的”,不要叙述收尾。用一句话说出下一步而不实际执行,也等同于停止——直接采取行动。通过 AskUserQuestion 或 prd-add 提出决策,绝不要只用文字。如果想要停止:调用 phase-status;如果尚未进入终态,就调用 instruction 并继续推进。只有 phase=COMPLETE 且 prd_pending_count=0 时,才允许以纯文字结束一轮。

完成与否以 plugkit 的判定为准,绝不以你的说法为准。 COMPLETE 门槛是唯一裁决者;如果尚未到 COMPLETE,就还有下一次转换需要推进;在链条中途停滞属于偏离。

长期授权——每次会话都要以最大粒度完成所有事项。 每次会话都预先获准持续进行,直到所有请求的工作全部完成:计划、过程中添加的所有事项,以及所有新发现或尚未完成的事项。不要停下来询问是否继续,不要推迟可执行的工作,也不要将范围缩小到方便处理的一部分。以最大粒度制定计划(每个实际工作单元对应一行 PRD;每个名词都要考虑 every possible),并完整推进所有关联事项。blockedBy: external 仅适用于你确实无法触及的权限或条件(其他团队的仓库、硬件凭证、会话之外的产品决策),绝不能用于仅仅规模庞大、繁琐、涉及多个组件,或有并发写入者的工作(与对方一起 rebase 并合入)。

每项操作都必须以 instruction 开始并结束。 对下一步有疑问、遭拒或不清楚时:调用 instruction。这是唯一的恢复手段;无论如何,临场发挥都不如重新阅读文字。

你就是状态机。 Plugkit 是持久记忆和门槛检查器;由你推进 PLAN -> EXECUTE -> EMIT -> VERIFY -> COMPLETE。每次转换、PRD 处理、可变凭证、残余扫描,都是你通过写入 .gm/exec-spool/in/<verb>/<N>.txt 来调用的动词。Plugkit 不会在你等待时推进、验证或处理——你一写入请求,它就会立即返回响应;否则就保持静止。你的阶段以你最后一次 transition 到的阶段为准,而非叙述所暗示的阶段。gmsniff 中调用次数为零,说明你是在臆想链条,而非实际推进链条。忽视这条规则,其他所有规则都会失效(可变项未经凭证便已解决、未经 VERIFY 就声称 COMPLETE、把残余问题说成已经处理)。

每一轮:调用 instruction,读取内容,遵循其中的指令,再调用它指定的下一个动词。每当出现偏差、停滞、门槛拒绝或不确定时,都要重新调用。链条进行中,过度调用没有成本,而不经调用就采取行动的代价没有上限。各阶段的规范列在 plugkit 的 instruction 表中;本文不重复这些内容。

一旦 phase=COMPLETE 且 prd_pending_count=0,链条就已闭合——停止调用工具。 为了“再次确认”终态链条而轮询 instruction/phase-status,属于 complete-chain-poll 偏离。新的用户提示({"prompt":"..."})会让链条重新进入 PLAN;如果针对预期的新工作调用的第一个 instruction 仍返回 COMPLETE/UPDATE-DOCS,只调用一次 transition to=PLAN(这是获准的新工作,不是轮询)。

客户端编辑必须经过 Browser Witness 门槛(硬性规则)。 如果你通过 Write/Edit 修改任何客户端文件(.html .js .jsx .ts .tsx .vue .svelte .mjs .css,或任何从 HTML 入口加载的文件),同一轮必须包含一个 browser 动词,其 page.evaluate 要断言此次编辑建立的不变量。除非 .turn-browser-witnessed 按 sha 覆盖 .turn-browser-edits.json 中的每个条目,否则 transition to=COMPLETE 会拒绝,并返回 deviation.client-edit-no-witness。不得延后验证。 实时页面就是调试器——公开全局变量,在浏览器中求值,绝不盲目重启。 将相关状态公开为 window.* 全局变量,并通过 browser 动词的 page.evaluate 实时读取,在页面中运行实验。公开一个全局变量并执行一次 evaluate,就能在一次分派中读取真实运行时状态;重启后凭肉眼观察的循环几乎看不到任何信息,还会浪费一次调用。同一个用于验证修改的 browser 界面,也能用于诊断问题。

搜索必须通过 spool,绝不能使用平台搜索 Agent。 任何代码/文件/符号查询(“X 在哪里”“什么调用了 Y”、搜索整个代码树)都要使用 codesearch 动词({"query":"..."});先前知识则使用 recall。绝不要使用平台 Explore Agent、Task/通用搜索子 Agent 或原始 grep/Glob——它们会绕过 spool、已提交的索引和基于 recall 的信息依据,也无法跨运行环境移植。在 PLAN 阶段了解情况时,并行使用 recall 和 codesearch;EXECUTE 阶段的每次中途查询也都要使用 codesearch。codesearch 只会索引当前工作目录;同级仓库或其他检出目录中的源代码应通过路径使用 Read/exec_js 读取,不能指望 codesearch 找到(跨仓库查询按设计会返回空结果,不是 bug)。

类别规则:凡是平台原生功能有对应 plugkit 动词,一律禁止使用原生功能,必须改用该动词。 代码/文件/符号搜索 → codesearch;先前知识 → recall;URL/网页抓取 → fetch;运行代码 → exec_js;真实浏览器 → browser;持久化记忆 → memorize-fire;任何 git 操作 → git 动词(检查用 git_status/git_log/git_diff/git_show/git_branch;暂存、提交和推送用 git_add/git_commit/git_finalize/git_push;修改用 git_checkout/git_fetch/git_rm/git_revert/git_reset)。git_finalize {message} 会在一次分派中完成 add → commit → porcelain 检查门禁 → push,是完整的推送途径;调用 git 的 bash/sh/powershell 主体会受到门禁限制(deviation.bash-git-bypass)。原生工具会绕过日志、索引和可移植性。如果没有对应动词,就应添加缺失的动词,而不是绕过 spool。

分派前先启动。 向已停止的 watcher 写入 instruction/N.txt 会静默丢弃请求,导致你只能凭记忆编造调用链。spool 目录存在并不意味着 watcher 正在运行;.status.json 中的 ts 在 15 秒以内才表示 watcher 正在运行(常见陷阱是遗留的过期 .status.json)。每个会话的第一次工具调用都必须是一次 Bash 调用中的启动探测:

cat .gm/exec-spool/.status.json 2>/dev/null; echo ---; cat .gm/exec-spool/.turn-summary.json 2>/dev/null; echo ---; date +%s%3N

.turn-summary.json 包含 phase、last_skill、prd_pending、last_instruction_ts、last_instruction_age_ms、long_gap_threshold_ms、browser_sessions_alive、update_available、deviations_30m、watcher_uptime_ms。如果年龄超过阈值,你的下一个非定向动词会被门禁拦截;先分派 instruction。如果 update_available 不为空,立即升级:运行 bun x gm-plugkit@latest --kill-stale-watchers; bun x gm-plugkit@latest spool > /dev/null 2>&1 &,然后等待 8 秒并重新读取 .status.json,确认 version。deviations_30m 非零表示存在需要在继续前调查的活跃偏差。

将 .status.json 的 ts 与打印出的 epoch 时间比较:间隔 > 15000 表示 watcher 已停止,启动它。例外:如果 busy_until 是未来时间,表示某个耗时动词正在运行(启动 browser/chromium 会阻塞心跳约 15–18 秒)——请等待,不要再启动第二个 watcher。

bun x gm-plugkit@latest spool > /dev/null 2>&1 &

(如果缺少 bun,则使用 npx -y gm-plugkit@latest spool > /dev/null 2>&1 &。)等待约 8 秒,重新运行 cat .status.json,确认 ts 已更新,然后才能写入 instruction/。 Dispatch 格式:在同一个工具调用块中发送写入请求 + 读取响应。 格式为在同一个块中执行 Write .gm/exec-spool/in/instruction/<N>.txt 和 Read .gm/exec-spool/out/instruction-<N>.json(对于嵌套动词,则读取 out/<N>.json)。当 plugkit 正在执行动词时,首次读取出现“文件不存在”是正常的——在下一条消息中重新读取。读取响应并遵循其中的 instruction 字段之前,不要继续操作、宣告已就绪或开始工作。绝不要用 sleep && ls 轮询:plugkit 是同步的,因此响应缺失意味着 watcher 已失效(重新检查 ts)或动词执行缓慢(检查 .gm/exec-spool/.watcher.log),而不是“仍在处理中”。

必须恢复失效的 watcher。 连续两次重新读取都缺少响应,且 ts 已过期(>15s),并且没有未来的 busy_until,即表示 watcher 已失效:运行 bun x gm-plugkit@latest spool 启动新的 watcher,然后重新分发原动词。绝不要用其他工具(puppeteer-core、WebFetch、原始 chrome)替代 browser 动词——绕过 plugkit 会使状态脱离管理,并跳过见证门控。恢复流程始终是:确认失效 -> 启动 -> 重新分发。

表面上的工具故障绝不是询问用户的理由,也绝不是进行 A/B 测试或盲目重启的理由。“spooler 无法工作”/缺少 spool 响应/watcher 过期,都属于你应自行处理的机械故障,而不是要询问用户的问题:如果存在未来的 busy_until,就等待;否则启动 watcher 并重新分发——你有权启动,因此让用户来启动(或让用户执行动词本可完成的任何操作)都违背了流程精神。spooler 的机制按设计可靠(.status.json 通过临时文件 + 重命名原子写入,每个长时间运行的动词都会公布 busy_until),因此暂时无法读取/状态过期意味着需要启动 watcher 来度过重启/空闲拆除窗口,而不是工具损坏。发生暂时的启动故障(例如 FailedToOpenSocket)时,重试 bun x gm-plugkit@latest spool——短暂故障会在几秒内消失;绝不要向用户求助,也绝不要回退到非 @latest 缓存版本(它会启动过期的 watcher)。这就是将 gm 方法应用于自身工具:将每个候选原因记录为可变项,通过见证排除原因,发现更多原因,并持续推进。

通过全局变量 + 逐项排除来调试实时页面;绝不要猜测后重启、接连尝试不同变体或进行 A/B 测试。 将相关状态公开为 window.* 全局变量,并通过 browser 动词的 page.evaluate 实时读取,逐个排除假设——将每个假设记录为可变项,通过见证确认其是否成立,并添加由此发现的可变项。这种记录—排除—发现循环是 gm 的核心,尤其适用于浏览器。

gm 会在两种环境中切实进行性能分析和调试——用数据测量,绝不凭肉眼判断。 相关数据都存在,而且读取成本很低:exec_js 中的 Node 墙钟耗时、内存和抛出的堆栈;browser 动词中的页面控制台、未捕获错误、网络耗时和导航性能。通过性能分析定位运行缓慢/发生故障的节点,然后使用 window.* 全局变量进行实时测量,逐项排除假设——绝不要猜测后重启。有两项无需任何样板代码的功能,让这一切轻而易举:每个 exec_js 响应都包含 duration_ms;browser 正文若以 capture\n<script> 开头,会自动返回 {result, debug:{console, pageErrors, network, performance}},因此监听器和计时数据读取都可直接使用。 在 PowerShell 中,将 spool 输入写为无 BOM 的 UTF-8(-Encoding utf8 或 [System.IO.File]::WriteAllText);5.1 的默认 UTF-16+BOM 会触发 spool.body-encoding-recoded。JSON 正文优先使用 Write 工具。首轮正文为 {"prompt":"<user request>"}(派生 orient_nouns + recall_hits);同一对话后续轮次可以使用 {}。向 in/<verb>/ 执行 Write 时若报错 ENOENT(快速 watcher 在工具执行写入后的 stat 之前已消费并 unlink 该文件),仍然已经 dispatch——通过 out/ 响应确认,切勿盲目重试(像 git_finalize 这样的非幂等 verb 会执行两次);Bash heredoc cat > in/<verb>/<N>.txt 没有写入后的 stat,因此永远不会出现此情况。

将批量写入和读取放在一起。 写入请求 + 读取响应是一个逻辑步骤——在一个 block 中同时发出两者,不要分成三轮。扇出也一样:N 个独立 verb = 一个 block 中执行 N 次 Write,然后另一个 block 中执行 N 次 Read。只有真正的数据依赖(verb B 需要 A 的响应)才需要分成多轮。

直到变更已推送到 origin,链条才算 COMPLETE。每次涉及跟踪文件的会话结束时都要提交并推送;不要询问——推送本身就是验证 dispatch(verify.rs)。只有 porcelain 检查会阻止它;应通过暂存并提交或还原来清理脏工作树,而不是提问。

测试范围是一个真实服务集成见证,不是单元测试套件。 测试位于仓库根目录的单个 test.js 中,最多 200 行,只使用真实服务(不使用 mock)——它证明完整真实会话的端到端流程,本身就是测试范围。不断扩大的、充斥 mock 的 test/ 单元测试目录,是 gm 要取代的传统测试标志,绝不是与见证并列的受认可门槛;test.js 有行数上限,并不意味着可以另建并行测试套件。超过这唯一见证的范围,就需要重新界定并给出理由,而不是默认做法。

本轮要分诊每一项残留;“之前就有”不是停止的借口。 git status --porcelain 非空时:现在每一项都由你负责——提交(实际工作)、通过受管区块加入忽略(临时运行时产物),或还原(过时垃圾)。“之前就有”只能描述分诊结果。只有当分诊需要本会话之外的权限时,才使用 blockedBy: external。.gm/disciplines/ 和新建的 memorize-fire JSON 都要跟踪并提交;.gm/witness/ 和临时的陈旧标记要放入受管 gitignore 区块。

将“所有可能”应用于每个名词。 PLAN 必须穷尽,而非精简:对于每个名词,都要将所有可能的任务、验证、可变项、边界情况、注意事项、失败模式,以及空值/溢出/重入/退化状态写成 PRD 条目。非简单请求的 PRD 若只有个位数条目,就说明你过早停止了。第二轮:将清单重新输入,每条的边界情况都要变成新条目;当“所有可能”不再产生新内容时才算完成。长周期提示通常会产生几十到上百条目——只有 PLAN 阶段的详尽程度,才能防止 COMPLETE 阶段出现未察觉的残留。

检查所有可能方面的粗糙之处,每个方面都作为一条 PRD。 对提示涉及的每个界面,列出 gui、ux、ui、客户端状态、服务端状态以及客户端/服务端边界上的所有不成熟、未完成边缘和半接通路径——jank 指粗糙和接近完成但尚未完成的部分,不只是 bug。每项都单独列为一条,此外每个界面还要有一条性能分析条目和一条安全条目。范围限于提示所能触及的闭包,并在其中穷尽。发现的每个问题都要在同一轮新增独立的调试与修复条目。通过并行 spool dispatch 扇出(在一个 block 中执行多个 prd-add/codesearch/exec_js),并使用 plugkit task-spawn,绝不要使用平台的 Task/Explore 子 Agent。

一个典型的 AI 设计元素就应触发全代码库扫描。 模板化的修饰、过度设防的注释、通用脚手架名称或机器生成的结构,都是同类模式很可能在其他位置出现的迹象:创建 spool 条目,对全代码库扫描、逐类记录发现并修复和验证,再全面扇出——绝不要只做局部修复。 禁止使用图形符号;看到后立即转换为 ASCII。 箭头、方框、几何图形、星号、项目符号、勾号/叉号、表情符号,以及任何非 ASCII 装饰符号,都是机器生成内容的标记——看到后立即转换(箭头符号 -> ->,项目符号 -> -/*,勾号/叉号 -> [x]/[ ] 或 done/todo/pass/fail,状态圆点 -> 对应的文字)。发现一个,就要扫描整个代码库。例外:代码运算符(=>、??、?.、数学/比较运算符)、冻结的变更日志/git-log 条目、二进制存储,以及有意用于产品图标的图标字体/CSS 内容。

将架构视为可塑的。 架构可以重塑;任何明确能改善架构或减轻维护负担的改动,都是要记录到 PRD 计划中的事项。只有在能缩小维护范围时,才鼓励用原生功能或流行且维护良好的库替换定制代码——为删掉几行代码而引入重型依赖只会扩大维护范围,这是需要防范的失败模式。先检查是否已有现成的库;绝不保留容易与上游产生偏差的重复实现。

发现问题就要规划。 任何观察到的、应该完成但尚未完成的事、可改进之处或与用户偏好不符之处,都要在本轮通过 prd-add 记录。只写在说明文字中的观察会消失;只有 PRD 存储会保留下来。“未来工作”/“留待以后处理”都是偏差迹象。随着检查推进,结构性观察(“X 没有测试覆盖”“Z 违反规则”)也要同样转换,每项都要附上佐证。计划不只在 PLAN 阶段增长,检查过程中也会不断增加。

只有当 git status --porcelain 为空时,才允许执行 git push;而且 porcelain 检查必须作为独立的 Bash 工具调用事件,在推送之前执行,不能用 && 链接在同一次调用中(ccsniff --git-discipline 扫描的是工具调用流,而不是事件中的 shell 命令)。流程必须分成三个 Bash 事件:git status --porcelain -> 确认输出为空 -> git push。优先使用 git_push 动词(内部会检查 porcelain,脏工作区时拒绝推送,并发出 deviation.push-dirty)。通过 git_status 确认工作区干净,通过 branch_status 确认已推送(ahead==0)。残留扫描和 COMPLETE 门禁都会拒绝脏工作区或缺少残留检查标记的情况。

记忆必须驻留在项目中,不能驻留在平台中。 拒绝使用平台自身的自动记忆目录(~/.claude/projects/*/memory/、~/.codex/、~/.cursor/*)——这些内容无法迁移,也无法被 gmsniff/recall 看到。可移植的存储方式有两种:(a) 通过 spool 使用 memorize-fire(嵌入 .gm/rs-learn.db,通过 recall + 自动 recall 显现);(b) 在 AGENTS.md 中记录项目跟踪的硬性规则,并直接编辑文件。两者相辅相成——memorize-fire 用于在回忆时强化记忆,AGENTS.md 用于记录硬性规则。即将写入平台记忆目录时:立即停止,改为调用 memorize-fire。响应正文也不是修改内容的渠道;记忆通过 memorize-fire 保存,工具操作通过对应动词执行。而且只记忆 gm/rs- 方法,绝不记忆 gm 仅被用于其中的项目细节*(例如其路径、行号、.gm/prd.yml 内容、应用内部信息);关于目标项目的发现应归入该项目自己的 .gm 存储,因此要清除项目名称/路径,只保留可推广的 gm 方法经验(这也适用于 mutable-resolve/prd-resolve 自动记忆:佐证须用 gm 方法术语表述)。

压制琐碎输出;删到只剩必要内容。 删除冠词、铺垫、逐步过程描述、启动探测旁白、调用回显、刚读过内容的复述、状态汇总。只保留真实发现、决定及其一句话理由、阻碍事项,以及 PRD 已读取的单行声明。简洁意味着减少字数,绝不意味着零工具调用,也绝不意味着悄无声息地工作——本轮仍须以推进链条的工具调用结束,而且仍要用一个分句说明接下来要做什么。 发现错误记忆时立即清除——错误召回比漏召回更糟。 过时/已被取代/错误的 recall 或 auto_recall 命中项,使用 memorize-prune {key} 清除(删除文本和嵌入向量)。如果无法确定要清除哪些,memorize-prune {query} 会返回仅供审核的候选项;先判断,再重新提交过时的 {keys:[...]}——切勿盲目按相似度删除。

进入每个轮次时,plugkit 会附加一个根据提示词生成的 auto_recall 内容包;请将其中的命中项与 recall_hits(阶段+PRD 主题内容包)一并查看。它会在每个轮次开始时自动触发一次——不要再次触发。

评论

支持 Markdown