printing-press-amend
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese/printing-press-amend
/printing-press-amend
Turn a dogfood session into a PR for a printed CLI in the public library.
bash
/printing-press-amend # auto-detect target CLI from session
/printing-press-amend superhuman # explicit short name
/printing-press-amend superhuman-pp-cli
/printing-press-amend ~/printing-press/library/superhumanThis skill lives in this repo (the machine) and acts on a printed CLI in the public library. It is sibling to (adds a new CLI), (improves a CLI pre-publish), and (reflects on the machine itself). None of those cover post-publish CLI amendments driven by real-session friction.
/printing-press-publish/printing-press-polish/printing-press-retroThe artifact this skill produces is semantically a "patch" (in the git/PR sense), tracked by the public library's source-comment convention and manifest. The slash-skill name is to disambiguate from the existing binary subcommand (which AST-injects pre-defined features — different mechanism, different intent).
// PATCH(...).printing-press-patches.jsonamendprinting-press patch将dogfood会话转换为公共库中已发布CLI的PR。
bash
/printing-press-amend # 从会话中自动检测目标CLI
/printing-press-amend superhuman # 显式指定短名称
/printing-press-amend superhuman-pp-cli
/printing-press-amend ~/printing-press/library/superhuman该技能位于此仓库(机器端),作用于公共库中的已发布CLI。它是(添加新CLI)、(发布前优化CLI)和(反思机器本身)的同类技能。上述技能均不支持由真实会话痛点驱动的发布后CLI修改。
/printing-press-publish/printing-press-polish/printing-press-retro本技能生成的产物在语义上是一个“补丁”(符合git/PR定义),通过公共库的源码注释约定和清单进行追踪。斜杠技能命名为,以区分现有的二进制子命令(该命令通过AST注入预定义功能——机制和意图均不同)。
// PATCH(...).printing-press-patches.jsonamendprinting-press patchSetup
配置
Before doing anything else:
<!-- PRESS_SETUP_CONTRACT_START -->
bash
undefined在执行任何操作前:
<!-- PRESS_SETUP_CONTRACT_START -->
bash
undefinedmin-binary-version: 4.0.0
min-binary-version: 4.0.0
Derive scope first — needed for local build detection
首先确定范围——用于本地构建检测
_scope_dir="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")"
_scope_dir="$(cd "$_scope_dir" && pwd -P)"
_scope_dir="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")"
_scope_dir="$(cd "$_scope_dir" && pwd -P)"
Prefer local build when running from inside the printing-press repo.
当在printing-press仓库内运行时,优先使用本地构建版本
_press_repo=false
if [ -x "$_scope_dir/printing-press" ] && [ -d "$_scope_dir/cmd/printing-press" ]; then
_press_repo=true
export PATH="$_scope_dir:$PATH"
echo "Using local build: $_scope_dir/printing-press"
elif ! command -v printing-press >/dev/null 2>&1; then
if [ -x "$HOME/go/bin/printing-press" ]; then
echo "printing-press found at ~/go/bin/printing-press but not on PATH."
echo "Add GOPATH/bin to your PATH: export PATH="$HOME/go/bin:$PATH""
else
echo "printing-press binary not found."
echo "Install with: go install github.com/mvanhorn/cli-printing-press/v4/cmd/printing-press@latest"
fi
return 1 2>/dev/null || exit 1
fi
_press_repo=false
if [ -x "$_scope_dir/printing-press" ] && [ -d "$_scope_dir/cmd/printing-press" ]; then
_press_repo=true
export PATH="$_scope_dir:$PATH"
echo "Using local build: $_scope_dir/printing-press"
elif ! command -v printing-press >/dev/null 2>&1; then
if [ -x "$HOME/go/bin/printing-press" ]; then
echo "printing-press found at ~/go/bin/printing-press but not on PATH."
echo "Add GOPATH/bin to your PATH: export PATH="$HOME/go/bin:$PATH""
else
echo "printing-press binary not found."
echo "Install with: go install github.com/mvanhorn/cli-printing-press/v4/cmd/printing-press@latest"
fi
return 1 2>/dev/null || exit 1
fi
Resolve and emit the absolute path the agent must use for every later
解析并输出代理后续每次调用printing-press
必须使用的绝对路径。上面的export PATH
仅影响本次Bash工具调用;后续调用会打开新的Shell,并根据用户默认PATH解析裸printing-press
命令,旧的全局版本可能会静默覆盖本地构建版本。代理会捕获此标记,并将绝对路径替换到后续所有调用中。
printing-pressexport PATHprinting-pressprinting-press
invocation. export PATH
above only affects this one
printing-pressexport PATH—
Bash tool call; subsequent calls open a fresh shell and resolve bare
—
printing-press
against the user's default PATH, where a stale global
printing-press—
can silently shadow the local build. The agent captures this marker and
—
substitutes the absolute path into every later invocation.
—
if [ "$_press_repo" = "true" ]; then
PRINTING_PRESS_BIN="$_scope_dir/printing-press"
else
PRINTING_PRESS_BIN="$(command -v printing-press 2>/dev/null || true)"
fi
echo "PRINTING_PRESS_BIN=$PRINTING_PRESS_BIN"
PRESS_BASE="$(basename "$scope_dir" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9-]/-/g; s/^-+//; s/-+$//')"
if [ -z "$PRESS_BASE" ]; then
PRESS_BASE="workspace"
fi
PRESS_SCOPE="$PRESS_BASE-$(printf '%s' "$_scope_dir" | shasum -a 256 | cut -c1-8)"
PRESS_HOME="$HOME/printing-press"
PRESS_RUNSTATE="$PRESS_HOME/.runstate/$PRESS_SCOPE"
PRESS_LIBRARY="$PRESS_HOME/library"
PRESS_MANUSCRIPTS="$PRESS_HOME/manuscripts"
PRESS_CURRENT="$PRESS_RUNSTATE/current"
mkdir -p "$PRESS_RUNSTATE" "$PRESS_LIBRARY" "$PRESS_MANUSCRIPTS" "$PRESS_CURRENT"
<!-- PRESS_SETUP_CONTRACT_END -->
After running the setup contract, capture the `PRINTING_PRESS_BIN=<abs-path>` line from stdout. **Every subsequent `printing-press ...` invocation in this skill must use that absolute path** (substitute the value, not the literal `$PRINTING_PRESS_BIN` token) — `export PATH` above only affects the single Bash tool call it runs in, so later calls open a fresh shell where bare `printing-press` resolves against the user's default `PATH` and a stale global can shadow the local build.
After capturing the binary path, check binary version compatibility. Read the `min-binary-version` field from this skill's YAML frontmatter. Run `<PRINTING_PRESS_BIN> version --json` and parse the version from the output. Compare it to `min-binary-version` using semver rules. If the installed binary is older than the minimum, stop immediately and tell the user: "printing-press binary vX.Y.Z is older than the minimum required vA.B.C. Run `go install github.com/mvanhorn/cli-printing-press/v4/cmd/printing-press@latest` to update."if [ "$_press_repo" = "true" ]; then
PRINTING_PRESS_BIN="$_scope_dir/printing-press"
else
PRINTING_PRESS_BIN="$(command -v printing-press 2>/dev/null || true)"
fi
echo "PRINTING_PRESS_BIN=$PRINTING_PRESS_BIN"
PRESS_BASE="$(basename "$scope_dir" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9-]/-/g; s/^-+//; s/-+$//')"
if [ -z "$PRESS_BASE" ]; then
PRESS_BASE="workspace"
fi
PRESS_SCOPE="$PRESS_BASE-$(printf '%s' "$_scope_dir" | shasum -a 256 | cut -c1-8)"
PRESS_HOME="$HOME/printing-press"
PRESS_RUNSTATE="$PRESS_HOME/.runstate/$PRESS_SCOPE"
PRESS_LIBRARY="$PRESS_HOME/library"
PRESS_MANUSCRIPTS="$PRESS_HOME/manuscripts"
PRESS_CURRENT="$PRESS_RUNSTATE/current"
mkdir -p "$PRESS_RUNSTATE" "$PRESS_LIBRARY" "$PRESS_MANUSCRIPTS" "$PRESS_CURRENT"
<!-- PRESS_SETUP_CONTRACT_END -->
运行配置合约后,从标准输出中捕获`PRINTING_PRESS_BIN=<abs-path>`行。**本技能中后续所有`printing-press ...`调用必须使用该绝对路径**(替换为实际值,而非字面量`$PRINTING_PRESS_BIN`)——上面的`export PATH`仅影响其运行的单个Bash工具调用,后续调用会打开新Shell,裸`printing-press`命令会根据用户默认PATH解析,旧的全局版本可能会静默覆盖本地构建版本。
捕获二进制路径后,检查二进制版本兼容性。从本技能的YAML前置元数据中读取`min-binary-version`字段。运行`<PRINTING_PRESS_BIN> version --json`并从输出中解析版本号。使用语义化版本(semver)规则与`min-binary-version`进行比较。如果已安装的二进制版本低于最低要求,立即停止并告知用户:"printing-press binary vX.Y.Z is older than the minimum required vA.B.C. Run `go install github.com/mvanhorn/cli-printing-press/v4/cmd/printing-press@latest` to update."Phase 0 — Input Mode Detection
阶段0 — 输入模式检测
This skill accepts two input sources for the finding list it later patches: a Claude Code session transcript (dogfood mode, current behavior) and user-supplied asks in the slash-command prompt (direct-input mode, added in v0.2). The two modes diverge only in Phase 1; Phase 2 onward is mode-agnostic and consumes a typed finding list with identical shape regardless of source.
Decide the mode before Phase 1 runs.
本技能接受两种输入来源作为后续补丁的需求列表:Claude Code会话记录(dogfood模式,当前默认行为)和斜杠命令提示符中的用户需求(直接输入模式,v0.2版本新增)。两种模式仅在阶段1存在差异;阶段2及以后与模式无关,均使用相同格式的结构化需求列表。
在阶段1运行前确定模式。
Detection rubric
检测规则
Read the slash-command prompt body and the immediate invocation turn from the conversation context. Classify into one of four branches:
-
— the prompt contains a concrete CLI name AND at least one direct-input signal:
MODE=direct- Action verbs targeting the CLI: ,
rename,add,remove,fix,sniffdiscover - Explicit URLs the user wants added (e.g., )
https://example.com/feed/x - An enumerated list of feeds, commands, endpoints, or features
- Phrasing like "these ideas", "these features", "with the following"
- Action verbs targeting the CLI:
-
— the prompt is empty, OR names a CLI without any asks ("amend the superhuman CLI"), OR explicitly references the session ("what I just dogfooded", "this session's friction", "from my session today")
MODE=dogfood -
— the prompt clearly references both: a session AND specific asks ("I dogfooded this session and also want to add feature X", "in addition to the friction I hit, please add command Y")
MODE=both -
Ambiguous — only one signal is present (CLI named with no verbs, or verbs with no target CLI, or asks worded so they could be friction reports OR new asks). Ask the user via:
AskUserQuestion"Two ways to source findings for this amend. Which fits?- Mine the current session transcript (dogfood mode)
- Use the asks I just typed (direct-input mode)
- Both — combine transcript friction with my asks"
Default when no slash-command prompt is present at all: . This preserves the canonical UX — with nothing after still works exactly as it did in v0.1.
MODE=dogfood/printing-press-amend读取斜杠命令提示符内容和对话上下文的即时调用回合。分为以下四个分支:
-
— 提示符包含具体的CLI名称AND至少一个直接输入信号:
MODE=direct- 针对CLI的动作动词:、
rename、add、remove、fix、sniffdiscover - 用户想要添加的明确URL(例如)
https://example.com/feed/x - 数据源、命令、端点或功能的枚举列表
- 类似"these ideas"、"these features"、"with the following"的表述
- 针对CLI的动作动词:
-
— 提示符为空,OR仅指定CLI名称而无需求("amend the superhuman CLI"),OR明确引用会话("what I just dogfooded"、"this session's friction"、"from my session today")
MODE=dogfood -
— 提示符明确同时引用会话和特定需求("I dogfooded this session and also want to add feature X"、"in addition to the friction I hit, please add command Y")
MODE=both -
模糊场景 — 仅存在一种信号(指定CLI但无动词,或有动词但无目标CLI,或需求表述既可视为痛点报告也可视为新需求)。通过询问用户:
AskUserQuestion"有两种方式为本次修改获取需求,请问哪种符合你的情况?- 挖掘当前会话记录(dogfood模式)
- 使用我刚刚输入的需求(直接输入模式)
- 两者结合——将会话痛点与我的需求合并"
当完全没有斜杠命令提示符时,默认使用。这保留了标准用户体验——不带任何参数时的行为与v0.1版本完全一致。
MODE=dogfood/printing-press-amendPersist the mode
持久化模式
Write the resolved mode to so later phases (and a resumed run) can read it:
$PRESS_RUNSTATE/current/mode.txtbash
echo "$MODE" > "$PRESS_RUNSTATE/current/mode.txt"将解析后的模式写入,以便后续阶段(以及恢复的运行)可以读取:
$PRESS_RUNSTATE/current/mode.txtbash
echo "$MODE" > "$PRESS_RUNSTATE/current/mode.txt"Output
输出
Phase 0 emits one line to Phase 1:
yaml
mode: <dogfood|direct|both>Phase 1 branches on this value — dogfood findings flow through , direct-input findings flow through , and combined runs execute both sub-sections in sequence. Phase 2 onward ignores the mode entirely — the finding list is the contract.
### 1a### 1b阶段0向阶段1输出一行内容:
yaml
mode: <dogfood|direct|both>阶段1根据该值分支处理——dogfood需求通过流程,直接输入需求通过流程,合并模式则依次执行两个子流程。阶段2及以后完全忽略模式——需求列表是唯一的契约。
### 1a### 1bPhase 1 — Capture
阶段1 — 捕获需求
This phase produces a typed finding list. The list shape is identical across modes: each finding carries , , , (bug or feature), , , , and ( for dogfood, for direct, for sniff-derived). Phase 2 consumes the list verbatim.
idkindcategoryclassificationevidencetarget_clirationaleprovenancetranscriptuser-asksniffWhen , run only . When , run only . When , run first, then , and merge the two finding lists with non-colliding IDs (1b continues numbering where 1a left off).
MODE=dogfood### 1aMODE=direct### 1bMODE=both### 1a### 1b本阶段生成结构化需求列表。所有模式下的列表格式相同:每个需求包含、、、(bug或feature)、、、和(dogfood模式为,直接输入模式为,探测衍生为)。阶段2会直接使用该列表。
idkindcategoryclassificationevidencetarget_clirationaleprovenancetranscriptuser-asksniff当时,仅运行。当时,仅运行。当时,先运行,再运行,并合并两个需求列表,确保ID不冲突(1b的ID从1a结束的编号开始)。
MODE=dogfood### 1aMODE=direct### 1bMODE=both### 1a### 1b1a. Dogfood mode (MODE=dogfood)
1a. Dogfood模式(MODE=dogfood)
Read for the full procedure. Summary of what this sub-section does:
references/transcript-parsing.md-
Resolve the active session transcript file — derivefrom the current working directory, list
<project-dir-slug>by mtime, pick the most-recently-modified. ALWAYS confirm the resolved path with the user via~/.claude/projects/<slug>/*.jsonlbefore reading — wrong-file selection ingests friction from the wrong session.AskUserQuestion -
Walk the transcript and extract friction signals — non-zero exit codes, error messages, hand-rolled API payloads (e.g. directPOSTs that should be a CLI command), retry-after-failure patterns, agent commentary like "X doesn't exist" / "X returns 400", missing-flag references, silent-null returns, auth confusion. Each signal carries timestamp + category + verbatim evidence + the
curlit references.<slug>-pp-cli -
Classify each signal as bug or feature with a one-line rationale. Bug = CLI behavior is wrong; feature = CLI behavior is missing. The classification is the agent's best read; the user confirms or overrides at the U4 scope checkpoint.
-
Auto-detect target CLI — count occurrences of eachin the signals, propose the most-touched CLI as the default. Confirm with
<slug>-pp-cli(single CLI: simple yes/no; multiple close: pick from list). When the user passed an explicitAskUserQuestionargument, skip auto-detect.<cli-name-or-path> -
Resolve target paths — accept short name, full name, or absolute path (per R4). Look up the public-library category by walkingfor a matching directory. The category is needed by U7's PR open phase and is captured here so it doesn't have to be re-derived.
~/printing-press-library/library/*/
Each finding emitted by 1a carries . Output flows into Phase 2 as the structured finding list documented in .
provenance: transcriptreferences/transcript-parsing.md完整流程请阅读。本小节流程摘要:
references/transcript-parsing.md-
解析当前会话记录文件 — 从当前工作目录派生,按修改时间列出
<project-dir-slug>,选择最新修改的文件。读取前必须通过~/.claude/projects/<slug>/*.jsonl与用户确认解析后的路径——选择错误文件会引入错误会话的痛点。AskUserQuestion -
遍历会话记录并提取痛点信号 — 非零退出码、错误消息、手动编写的API负载(例如应使用CLI命令而直接调用的POST请求)、失败后重试模式、代理注释如"X不存在" / "X返回400"、缺失标志位引用、静默返回空值、认证困惑。每个信号包含时间戳 + 类别 + 原文证据 + 引用的
curl。<slug>-pp-cli -
将每个信号分类为bug或feature,并附上一行理由。Bug = CLI行为错误;feature = CLI缺少某项功能。分类是代理的最佳判断;用户会在U4范围检查点确认或覆盖。
-
自动检测目标CLI — 统计每个在信号中的出现次数,将出现最频繁的CLI作为默认建议。通过
<slug>-pp-cli确认(单个CLI:简单是/否;多个相近选项:从列表中选择)。当用户传入了明确的AskUserQuestion参数时,跳过自动检测。<cli-name-or-path> -
解析目标路径 — 接受短名称、完整名称或绝对路径(遵循R4规则)。通过遍历查找匹配目录,确定公共库类别。该类别在U7的PR提交阶段需要用到,因此在此处捕获以避免重复解析。
~/printing-press-library/library/*/
1a生成的每个需求均带有。输出作为结构化需求列表流入阶段2,格式参考。
provenance: transcriptreferences/transcript-parsing.md1b. Direct-input mode (MODE=direct)
1b. 直接输入模式(MODE=direct)
Read for the full procedure (introduced in v0.2). Summary of what this sub-section does:
references/direct-input-parsing.md-
Read the slash-command prompt body plus the immediate agent-message turn that fired the skill — these carry the user's verbatim asks (e.g., "rename Digg 1000 to Digg, add these four feeds: ..., sniff for new endpoints"). There is no transcript to confirm; skip the U1 transcript-path modal that 1a runs.
-
Resolve the target CLI — same name-resolution rules as 1a step 4-5 (per R4), but the CLI is normally already named in the prompt itself. Extract via regex (or "the <slug> CLI"); if absent, ask the user.
<slug>-pp-cli -
Parse the asks into structured findings using the rubric in. Each ask maps to one finding with a typed
references/direct-input-parsing.mdfield:kind- — "rename X to Y" / "call it X instead of Y" →
renameclassification: feature - — "add command X" / "add subcommand X" →
add-commandclassification: feature - — "add feed <url>" / enumerated URLs the user wants added (one finding per URL) →
add-feedclassification: feature - — "add endpoint <url>" / explicit API path →
add-endpointclassification: feature - — "fix X" / "X is broken" / "X returns null" →
fix-bugclassification: bug - — "sniff for new APIs" / "find new endpoints" / "discover more" → routes to the sniff subroutine in
sniff### 1b.i
-
Each finding records the user's verbatim phrasing inso the U4 scope confirmation modal shows the user what they actually wrote.
evidence -
Edge cases — multi-CLI asks split into two separate runs (out of scope for v0.2; ask the user to pick one). Ambiguous verbs (without specifics) trigger an
update Xclarification rather than a guess.AskUserQuestion
Each finding emitted by 1b carries (or for findings produced by the sniff subroutine). Output flows into Phase 2 as the same structured finding list shape used by 1a.
provenance: user-askprovenance: sniff完整流程请阅读(v0.2版本引入)。本小节流程摘要:
references/direct-input-parsing.md-
读取斜杠命令提示符内容以及触发技能的即时代理消息回合——这些包含用户的原始需求(例如"rename Digg 1000 to Digg, add these four feeds: ..., sniff for new endpoints")。无需确认会话记录;跳过1a中运行的U1会话路径弹窗。
-
解析目标CLI — 与1a步骤4-5使用相同的名称解析规则(遵循R4),但CLI通常已在提示符中指定。通过正则表达式提取(或"the <slug> CLI");如果未找到,询问用户。
<slug>-pp-cli -
将需求解析为结构化需求,使用中的规则。每个需求映射为一个带有
references/direct-input-parsing.md字段的结构化条目:kind- — "rename X to Y" / "call it X instead of Y" →
renameclassification: feature - — "add command X" / "add subcommand X" →
add-commandclassification: feature - — "add feed <url>" / 用户想要添加的枚举URL(每个URL对应一个需求)→
add-feedclassification: feature - — "add endpoint <url>" / 明确的API路径 →
add-endpointclassification: feature - — "fix X" / "X is broken" / "X returns null" →
fix-bugclassification: bug - — "sniff for new APIs" / "find new endpoints" / "discover more" → 路由到
sniff中的探测子流程### 1b.i
-
每个需求记录用户的原始表述在字段中,以便U4范围确认弹窗显示用户实际输入的内容。
evidence -
边缘情况 — 多CLI需求拆分为两个独立运行(v0.2版本暂不支持;请用户选择一个)。模糊动词(无具体内容的)触发
update X澄清,而非猜测。AskUserQuestion
1b生成的每个需求均带有(或由探测子流程生成的需求带有)。输出作为与1a相同格式的结构化需求列表流入阶段2。
provenance: user-askprovenance: sniff1b.i. Sniff-finding subroutine
1b.i. 探测需求子流程
Triggered when the parsing rubric tags any 1b ask as (phrases like "sniff for new APIs", "find new endpoints", "discover more endpoints in <site>"). Sniff is opt-in per run — never invoked unless the user named it. Skip this subroutine entirely when no sniff finding is present.
kind: sniffStep 1 — Resolve the target source URL. Read the target CLI's published manifest at and extract (or as fallback). Category was resolved in 1b step 2.
~/printing-press-library/library/<category>/<slug>/.printing-press.jsonsource_urlspec_urlIf neither field is set, ask the user inline:
"Sniff needs a target URL — paste the source site you want sniffed, or skip the sniff finding for this run?"
If the user skips, drop the sniff finding from the active list and continue with the other 1b findings. If the user pastes a URL, use it for steps 2-3.
Step 2 — Run crowd-sniff first (fast, no browser). Replace with the absolute path captured at setup:
<PRINTING_PRESS_BIN>bash
<PRINTING_PRESS_BIN> crowd-sniff --site "$SOURCE_URL" --json > /tmp/amend-sniff-crowd.json
crowd_exit=$?crowd-sniffStep 3 — Optional browser-sniff (only when the user opted in deeper). When the user's ask explicitly named browser-based discovery ("sniff with browser", "do a deep sniff") AND a captured HAR is already available, run:
bash
<PRINTING_PRESS_BIN> browser-sniff --har "$HAR_PATH" --json > /tmp/amend-sniff-browser.json
browser_exit=$?This skill does not orchestrate HAR capture itself in v0.2 — capture is user-driven (the user opens the source site in Chrome, exports the HAR, and points the skill at it) or the deep sniff is skipped with a note. v0.3 may extend the skill to drive capture via the claude-in-chrome MCP; out of scope for v0.2.
Step 4 — Convert discoveries to findings. For each candidate endpoint in the sniff output, append one finding to the 1b finding list:
- (next available number after the parsed asks)
id: F<n> kind: add-endpointclassification: feature- (or
evidence: "discovered via crowd-sniff: <endpoint-path>"when applicable)browser-sniff target_cli: <slug>-pp-clirationale: <one-line summary from sniff output if available, otherwise "sniff candidate, user to confirm">provenance: sniff
Tier these as Tier 3 (polish/architecture) at Phase 3 by default — the user reviews and can promote individual entries to Tier 2 if they're high-priority.
Step 5 — Degraded paths.
| Condition | Behavior |
|---|---|
| Drop sniff finding; continue with other 1b findings; log "sniff skipped — no source URL". |
| Log the error; skip sniff findings; continue with other 1b findings. Do NOT abort the amend run. |
| Emit one entry to the deferred-findings list ("sniff ran, no new endpoints discovered") rather than adding nothing — gives the user a record. |
| Browser-sniff requested but no HAR available | Log; fall back to crowd-sniff results only. |
Step 6 — Surface provenance to the user. At the Phase 3 scope-confirmation modal, sniff-derived findings are visually grouped under a provenance tag so the user can decide whether to keep them as a group, e.g.:
(sniff)Tier 3 — Polish / architecture (5)
F8 add-endpoint /v1/feeds/stars (sniff)
F9 add-endpoint /v1/feeds/new (sniff)
F10 add-endpoint /v1/feeds/activity (sniff)
...当解析规则将任何1b需求标记为时触发(例如"sniff for new APIs"、"find new endpoints"、"discover more endpoints in <site>"等表述)。探测是每次运行的可选功能——仅当用户明确指定时才会调用。当没有探测需求时,完全跳过本子流程。
kind: sniff步骤1 — 解析目标源URL。读取目标CLI在中的已发布清单,提取(或作为备选)。类别已在1b步骤2中解析。
~/printing-press-library/library/<category>/<slug>/.printing-press.jsonsource_urlspec_url如果两个字段均未设置,在线询问用户:
"Sniff需要目标URL — 请粘贴要探测的源站点URL,或跳过本次运行的探测需求?"
如果用户跳过,从当前需求列表中移除探测需求,继续处理其他1b需求。如果用户粘贴了URL,将其用于步骤2-3。
步骤2 — 先运行crowd-sniff(快速,无需浏览器)。将替换为配置阶段捕获的绝对路径:
<PRINTING_PRESS_BIN>bash
<PRINTING_PRESS_BIN> crowd-sniff --site "$SOURCE_URL" --json > /tmp/amend-sniff-crowd.json
crowd_exit=$?crowd-sniff步骤3 — 可选的browser-sniff(仅当用户选择深度探测时)。当用户的需求明确指定基于浏览器的发现("sniff with browser"、"do a deep sniff")AND已捕获HAR文件时,运行:
bash
<PRINTING_PRESS_BIN> browser-sniff --har "$HAR_PATH" --json > /tmp/amend-sniff-browser.json
browser_exit=$?v0.2版本中,本技能不负责协调HAR捕获——捕获由用户驱动(用户在Chrome中打开源站点,导出HAR,并指向技能)或跳过深度探测并记录说明。v0.3版本可能扩展技能以通过claude-in-chrome MCP驱动捕获;v0.2版本暂不支持。
步骤4 — 将发现转换为需求。对于探测输出中的每个候选端点,向1b需求列表追加一个需求:
- (解析需求后的下一个可用编号)
id: F<n> kind: add-endpointclassification: feature- (或适用时为
evidence: "discovered via crowd-sniff: <endpoint-path>")browser-sniff target_cli: <slug>-pp-clirationale: <探测输出中的一行摘要(如果有),否则为"sniff candidate, user to confirm">provenance: sniff
默认在阶段3将这些需求归类为Tier 3(优化/架构)——用户会进行审核,并可将个别条目提升为Tier 2(高优先级)。
步骤5 — 降级路径
| 条件 | 行为 |
|---|---|
| 移除探测需求;继续处理其他1b需求;记录"sniff skipped — no source URL"。 |
| 记录错误;跳过探测需求;继续处理其他1b需求。不要中止修改运行。 |
| 向延迟需求列表添加一个条目("sniff ran, no new endpoints discovered"),而非什么都不添加——为用户提供记录。 |
| 请求browser-sniff但无HAR可用 | 记录;仅使用crowd-sniff结果。 |
步骤6 — 向用户展示来源。在阶段3的范围确认弹窗中,探测衍生的需求会在视觉上分组到来源标签下,以便用户决定是否保留整个组,例如:
(sniff)Tier 3 — 优化 / 架构 (5)
F8 add-endpoint /v1/feeds/stars (sniff)
F9 add-endpoint /v1/feeds/new (sniff)
F10 add-endpoint /v1/feeds/activity (sniff)
...Phase 2 — Pre-Checkpoint Guards
阶段2 — 检查点前置守卫
Two guards run before the user sees the scope menu. Either can suppress findings or abort the run.
在用户看到范围菜单前,运行两个守卫。任一守卫均可抑制需求或中止运行。
2a. PR cross-reference (suppress duplicate proposals)
2a. PR交叉引用(抑制重复提案)
For each finding from Phase 1, search open + recently-merged PRs in for matches. The duplicate-detection criteria (in priority order): (1) the target CLI's directory path overlaps the PR's changed-file list, (2) keywords from the finding's category + rationale match the PR title or body.
mvanhorn/printing-press-librarybash
undefined对于阶段1的每个需求,在的开放+最近合并PR中搜索匹配项。重复检测标准(按优先级排序):(1) 目标CLI的目录路径与PR的变更文件列表重叠,(2) 需求类别+理由中的关键词与PR标题或正文匹配。
mvanhorn/printing-press-librarybash
undefinedReplace <PRINTING_PRESS_BIN> use with the absolute path captured at setup.
将<PRINTING_PRESS_BIN>替换为配置阶段捕获的绝对路径。
This phase uses gh, not the press binary.
本阶段使用gh,而非press二进制。
Open PRs touching this CLI
涉及此CLI的开放PR
gh pr list --repo mvanhorn/printing-press-library
--search "in:title,body <slug>" --state open --limit 20
--json number,title,state,headRefName,files
--search "in:title,body <slug>" --state open --limit 20
--json number,title,state,headRefName,files
gh pr list --repo mvanhorn/printing-press-library
--search "in:title,body <slug>" --state open --limit 20
--json number,title,state,headRefName,files
--search "in:title,body <slug>" --state open --limit 20
--json number,title,state,headRefName,files
Recently merged PRs (last 90 days) touching this CLI.
最近合并的PR(过去90天)涉及此CLI。
Compute "90 days ago" portably — date -v-90d
is BSD/macOS only, date -d
date -v-90ddate -d可移植计算"90天前"的日期——date -v-90d
仅适用于BSD/macOS,date -d
仅适用于GNU/Linux。先尝试GNU格式,再尝试BSD格式,最后尝试python3。如果所有格式均失败,明确错误中止,而非让去重守卫因空的merged:>
限定符而静默退出。
date -v-90ddate -dmerged:>is GNU/Linux only. Try GNU first, fall back to BSD, then to python3. If
—
every form fails, abort with an explicit error rather than letting the
—
dedup guard silently drop out with an empty merged:>
qualifier.
merged:>—
ninety_days_ago=$(date -u -d '90 days ago' +%Y-%m-%d 2>/dev/null
|| date -u -v-90d +%Y-%m-%d 2>/dev/null
|| python3 -c 'import datetime; print((datetime.datetime.now(datetime.UTC).date() - datetime.timedelta(days=90)).isoformat())' 2>/dev/null) if [ -z "$ninety_days_ago" ]; then echo "ERROR: cannot compute 90-days-ago date — no GNU date, BSD date, or python3 available." exit 1 fi
|| date -u -v-90d +%Y-%m-%d 2>/dev/null
|| python3 -c 'import datetime; print((datetime.datetime.now(datetime.UTC).date() - datetime.timedelta(days=90)).isoformat())' 2>/dev/null) if [ -z "$ninety_days_ago" ]; then echo "ERROR: cannot compute 90-days-ago date — no GNU date, BSD date, or python3 available." exit 1 fi
gh pr list --repo mvanhorn/printing-press-library
--search "in:title,body <slug> merged:>$ninety_days_ago"
--state merged --limit 20
--json number,title,state,mergedAt,headRefName,files
--search "in:title,body <slug> merged:>$ninety_days_ago"
--state merged --limit 20
--json number,title,state,mergedAt,headRefName,files
For each finding with a possible-duplicate match, present inline:
> "Finding `F<n>` (`<category>`) may already be addressed by PR #<num> — `<title>` (<state>, <date>). Skip this finding?"
User options: skip (drops to deferred), keep, or "show me PR #<num>" (opens `gh pr view <num> --repo mvanhorn/printing-press-library --web`). The default for clearly-merged matches is "skip"; for open PRs, default is "keep" (the user may want to add to the in-flight PR rather than open a new one).
This guard catches the canonical failure mode from the 2026-05-15 dogfood: proposing auto-refresh for a Printing Press CLI when a similar PR had already shipped on a sibling CLI a few hours earlier. The cost of a false skip is low (the user can re-add via custom selection at U4); the cost of a false-negative duplicate is a rejected PR + reviewer time.ninety_days_ago=$(date -u -d '90 days ago' +%Y-%m-%d 2>/dev/null
|| date -u -v-90d +%Y-%m-%d 2>/dev/null
|| python3 -c 'import datetime; print((datetime.datetime.now(datetime.UTC).date() - datetime.timedelta(days=90)).isoformat())' 2>/dev/null) if [ -z "$ninety_days_ago" ]; then echo "ERROR: cannot compute 90-days-ago date — no GNU date, BSD date, or python3 available." exit 1 fi
|| date -u -v-90d +%Y-%m-%d 2>/dev/null
|| python3 -c 'import datetime; print((datetime.datetime.now(datetime.UTC).date() - datetime.timedelta(days=90)).isoformat())' 2>/dev/null) if [ -z "$ninety_days_ago" ]; then echo "ERROR: cannot compute 90-days-ago date — no GNU date, BSD date, or python3 available." exit 1 fi
gh pr list --repo mvanhorn/printing-press-library
--search "in:title,body <slug> merged:>$ninety_days_ago"
--state merged --limit 20
--json number,title,state,mergedAt,headRefName,files
--search "in:title,body <slug> merged:>$ninety_days_ago"
--state merged --limit 20
--json number,title,state,mergedAt,headRefName,files
对于每个可能存在重复匹配的需求,在线展示:
> "需求`F<n>`(`<category>`)可能已由PR #<num>解决 — `<title>`(<state>, <date>)。是否跳过此需求?"
用户选项:跳过(移至延迟列表)、保留,或"show me PR #<num>"(打开`gh pr view <num> --repo mvanhorn/printing-press-library --web`)。对于明确已合并的匹配项,默认选择"跳过";对于开放PR,默认选择"保留"(用户可能希望添加到正在进行的PR中,而非打开新PR)。
此守卫解决了2026-05-15 dogfood中的典型失败模式:当某个Printing Press CLI的类似PR已在几小时前发布到兄弟CLI时,仍提议为该CLI添加自动刷新功能。错误跳过的成本很低(用户可在U4通过自定义选择重新添加);错误未检测到重复的成本是PR被拒绝+审核者时间浪费。2b. Stale-binary check (abort if the dogfooded binary lags published)
2b. 旧版本二进制检查(如果dogfood使用的二进制落后于已发布版本则中止)
Read the public library's for the target CLI to find the published version. Compare to what the local printed CLI binary reports.
.printing-press.jsonbash
undefined读取目标CLI在公共库中的以查找已发布版本。与本地已生成的CLI二进制版本进行比较。
.printing-press.jsonbash
undefinedRead published version (managed clone if available, else gh api)
读取已发布版本(如果有托管克隆则使用,否则使用gh api)
if [ -f "$HOME/printing-press-library/library/<category>/<slug>/.printing-press.json" ]; then
published=$(jq -r '.version // empty' "$HOME/printing-press-library/library/<category>/<slug>/.printing-press.json")
else
published=$(gh api repos/mvanhorn/printing-press-library/contents/library/<category>/<slug>/.printing-press.json
--jq '.content' | base64 -d | jq -r '.version // empty') fi
--jq '.content' | base64 -d | jq -r '.version // empty') fi
if [ -f "$HOME/printing-press-library/library/<category>/<slug>/.printing-press.json" ]; then
published=$(jq -r '.version // empty' "$HOME/printing-press-library/library/<category>/<slug>/.printing-press.json")
else
published=$(gh api repos/mvanhorn/printing-press-library/contents/library/<category>/<slug>/.printing-press.json
--jq '.content' | base64 -d | jq -r '.version // empty') fi
--jq '.content' | base64 -d | jq -r '.version // empty') fi
Read local binary version (if installed; the user dogfooded with this binary)
读取本地二进制版本(如果已安装;用户使用此二进制进行dogfood)
local_ver=$(<slug>-pp-cli version --json 2>/dev/null | jq -r '.version // empty' || echo "")
If `local_ver` is older than `published` (semver comparison), abort cleanly:
> "The `<slug>-pp-cli` binary you dogfooded is v`<local_ver>`, but the published library version is v`<published>`. The friction you hit may already be fixed in the published version. Run:
>
> go install github.com/mvanhorn/<slug>-pp-cli@latest
>
> ...then re-run `/printing-press-amend` after re-dogfooding. Aborting this run."
Edge cases: if `.printing-press.json` is missing or has no `version` field, skip the stale check with a note. If the CLI is local-only (not yet published), skip the check.local_ver=$(<slug>-pp-cli version --json 2>/dev/null | jq -r '.version // empty' || echo "")
如果`local_ver`比`published`旧(语义化版本比较),则干净中止:
> "你用于dogfood的`<slug>-pp-cli`二进制版本是v`<local_ver>`,但公共库中的已发布版本是v`<published>`。你遇到的痛点可能已在已发布版本中修复。请运行:
>
> go install github.com/mvanhorn/<slug>-pp-cli@latest
>
> ...然后重新进行dogfood后,再运行`/printing-press-amend`。本次运行中止。"
边缘情况:如果`.printing-press.json`缺失或无`version`字段,记录说明并跳过旧版本检查。如果CLI仅为本地版本(尚未发布),跳过检查。Output
输出
Phase 2 emits the (possibly trimmed) finding list to Phase 3:
yaml
findings_kept:
- <finding from Phase 1>
findings_suppressed:
- id: F3
reason: "Duplicate of PR #571 (merged 2026-05-13)"
target_binary_check: { local: "1.0.0", published: "1.0.0", status: "current" }阶段2向阶段3输出(可能已修剪的)需求列表:
yaml
findings_kept:
- <来自阶段1的需求>
findings_suppressed:
- id: F3
reason: "Duplicate of PR #571 (merged 2026-05-13)"
target_binary_check: { local: "1.0.0", published: "1.0.0", status: "current" }Phase 3 — Scope Confirmation Checkpoint (User-in-Loop #1)
阶段3 — 范围确认检查点(用户参与环节#1)
This is the first of two user checkpoints. Everything until now has been read-only discovery; this checkpoint commits scope.
这是两个用户检查点中的第一个。到目前为止的所有操作均为只读发现;此检查点确认修改范围。
Tier the surviving findings
对剩余需求进行分层
Group findings into three tiers:
- Tier 1 — Bugs — every finding with . CLI behavior is wrong; fixes restore correctness.
classification: bug - Tier 2 — Missing features that solve immediate session pain — findings tied to a hand-rolled workaround the user actually built during the session (i.e. the user clearly needed it now, not theoretically).
classification: feature - Tier 3 — Polish / architecture — remaining findings that are nice-to-have or architectural improvements without an immediate workaround in the session.
classification: feature
Display the tiered list inline before the question:
Friction found for <slug>-pp-cli (12 signals, 2 suppressed as duplicates):
Tier 1 — Bugs (4)
F1 drafts list returns 400 silently
F4 messages query returns data: null
F7 refresh-token expiry not surfaced in errors
F11 ai --query returns code 500
Tier 2 — Missing features that solve session pain (4)
F2 no `drafts new` command (user hand-rolled writeMessage payload)
F5 no `--type sent` for threads list (user worked around with messages query)
F8 no `--remind-in <duration>` flag for send (user manually re-flagged drafts)
F10 no `bootstrap` to local SQLite (user did 50+ thread API calls)
Tier 3 — Polish / architecture (2)
F12 `auth status` doesn't link to `auth login` when refresh expired
F13 doctor doesn't surface stale-binary warning vs. published version将需求分为三个层级:
- Tier 1 — Bugs — 所有的需求。CLI行为错误;修复可恢复正确性。
classification: bug - Tier 2 — 解决即时会话痛点的缺失功能 — 需求,且用户在会话中实际构建了手动替代方案(即用户现在明确需要该功能,而非理论上需要)。
classification: feature - Tier 3 — 优化 / 架构 — 剩余的需求,属于锦上添花或架构改进,会话中无即时替代方案。
classification: feature
在问题前内联展示分层列表:
为<slug>-pp-cli发现的痛点(12个信号,2个因重复被抑制):
Tier 1 — Bugs (4)
F1 drafts列表静默返回400
F4 messages查询返回data: null
F7 refresh-token过期未在错误中显示
F11 ai --query返回代码500
Tier 2 — 解决会话痛点的缺失功能 (4)
F2 无`drafts new`命令(用户手动编写writeMessage负载)
F5 threads列表无`--type sent`选项(用户通过messages查询解决)
F8 send命令无`--remind-in <duration>`标志(用户手动重新标记草稿)
F10 无引导到本地SQLite的`bootstrap`命令(用户进行了50+次线程API调用)
Tier 3 — 优化 / 架构 (2)
F12 `auth status`在刷新过期时未链接到`auth login`
F13 doctor未显示与已发布版本相比的旧版本二进制警告Pick scope via AskUserQuestion
通过AskUserQuestion选择范围
Which scope should this patch cover?
1. Bugs only (Tier 1) — 4 findings
2. Bugs + immediate features (Tier 1 + Tier 2) — 8 findings
3. All tiers (Tier 1 + Tier 2 + Tier 3) — 10 findings
4. Custom selection — pick individual findingsThe options must be self-contained (each label must convey what it does without relying on description text — some harnesses hide the description).
AskUserQuestionFor the custom selection path: present a multi-select with each finding's id + category + one-line rationale; confirm the user-checked subset before proceeding.
此补丁应覆盖哪些范围?
1. 仅修复Bugs(Tier 1) — 4个需求
2. Bugs + 即时功能(Tier 1 + Tier 2) — 8个需求
3. 所有层级(Tier 1 + Tier 2 + Tier 3) — 10个需求
4. 自定义选择 — 挑选单个需求AskUserQuestion对于自定义选择路径:展示每个需求的id + 类别 + 一行理由的多选框;在继续前确认用户选中的子集。
Persist the excluded findings
持久化排除的需求
For every finding NOT in the confirmed scope, append to a deferred-list markdown file at:
$PRESS_MANUSCRIPTS/<api-slug>/<run-id>/proofs/<timestamp>-amend-<cli-name>-deferred.mdThe is a fresh timestamped id for this amend run (e.g. ). Format the deferred file as a YAML preamble + a finding-per-section markdown body so a future run on the same CLI can re-surface the items.
<run-id>amend-2026-05-15T1432/printing-press-amendyaml
---
date: 2026-05-15
target_cli: superhuman-pp-cli
amend_run_id: amend-2026-05-15T1432
deferred_count: 2
---Then one section per deferred finding with: id, category, classification, rationale, evidence, reason-deferred (e.g. "user picked Tier 1 only"), and .
still_relevant: unknownOn a subsequent run, Phase 3 should look in for the most-recent and offer the user the option to include any items still relevant in this run's scope. (Implementation note: this re-surfacing logic ships in v0.1; do not silently re-add — always present and confirm.)
/printing-press-amend$PRESS_MANUSCRIPTS/<api-slug>/*-deferred.md对于每个未包含在确认范围内的需求,追加到延迟列表markdown文件:
$PRESS_MANUSCRIPTS/<api-slug>/<run-id>/proofs/<timestamp>-amend-<cli-name>-deferred.md<run-id>amend-2026-05-15T1432/printing-press-amendyaml
---
date: 2026-05-15
target_cli: superhuman-pp-cli
amend_run_id: amend-2026-05-15T1432
deferred_count: 2
---然后每个延迟需求对应一个章节,包含:id、类别、分类、理由、证据、延迟原因(例如"用户仅选择Tier 1"),以及。
still_relevant: unknown在后续的运行中,阶段3应在中查找最新的文件,并向用户提供选项,将任何仍相关的条目包含在本次运行的范围内。(实现说明:此重新展示逻辑在v0.1版本发布;不要静默重新添加——始终展示并确认。)
/printing-press-amend$PRESS_MANUSCRIPTS/<api-slug>/*-deferred.mdEdge case: nothing to do
边缘情况:无操作可执行
If Phase 2 suppressed every finding (everything was a duplicate), Phase 3 reports cleanly and exits without opening the menu:
"All findings from this session were addressed by existing PRs. No novel patches found."
如果阶段2抑制了所有需求(所有需求均为重复),阶段3会干净地报告并退出,不打开菜单:
"本次会话的所有需求均已由现有PR解决。未发现新的补丁需求。"
Output
输出
Phase 3 emits to Phase 4:
yaml
scope_tier: bugs+features # or bugs|all|custom
findings_active: [...] # the user-confirmed subset
findings_deferred_path: <path> # where the deferred file landed阶段3向阶段4输出:
yaml
scope_tier: bugs+features # 或bugs|all|custom
findings_active: [...] # 用户确认的子集
findings_deferred_path: <path> # 延迟文件的路径Phase 4 — Plan + Execute + Validate (Autonomous)
阶段4 — 规划 + 执行 + 验证(自主运行)
This phase runs unattended between checkpoints 1 and 2. The user does not see fix-by-fix details; they review the final diff at the Phase 6 PR-draft checkpoint.
本阶段在检查点1和2之间无人值守运行。用户不会看到逐个修复的细节;他们会在阶段6的PR草稿检查点审核最终差异。
Step 1 — Set up the managed clone
步骤1 — 设置托管克隆
Per the Pre-Implementation Decision in the plan: this skill operates DIRECTLY on the managed clone of rather than on . The managed clone is at:
mvanhorn/printing-press-library$PRESS_LIBRARY/<slug>/$PRESS_HOME/.publish-repo-$PRESS_SCOPEThis is the same clone uses (Step 5 of that skill). Reuse it:
/printing-press-publishbash
PUBLISH_REPO_DIR="$PRESS_HOME/.publish-repo-$PRESS_SCOPE"
PUBLISH_CONFIG="$PRESS_HOME/.publish-config-$PRESS_SCOPE.json"
if [ ! -d "$PUBLISH_REPO_DIR/.git" ]; then
# First-time setup: see references/library-pr-plumbing.md for the full
# detection (push-vs-fork access via gh api .../permissions.push,
# SSH-vs-HTTPS protocol detection, scoped-clone cleanup loop).
echo "Managed clone not present — bootstrapping..."
# ... (see library-pr-plumbing.md)
else
# Refresh from upstream. -f on checkout discards any local edits left behind
# by a prior run that aborted between Phase 4's edits and Phase 7's commit —
# without -f, those uncommitted changes block the checkout and the subsequent
# reset --hard never runs.
cd "$PUBLISH_REPO_DIR"
git fetch upstream main
git checkout -f main
git reset --hard upstream/main
fiThe CLI's directory inside the managed clone is . The category was resolved in Phase 1 (or look it up with ).
$PUBLISH_REPO_DIR/library/<category>/<slug>/find "$PUBLISH_REPO_DIR/library" -maxdepth 2 -name "<slug>" -type dbash
CLI_DIR="$PUBLISH_REPO_DIR/library/<category>/<slug>"All edits in this phase happen INSIDE . Never touch — that's a different working copy and editing it would not flow to the PR.
$CLI_DIR$PRESS_LIBRARY/<slug>/根据计划中的预实现决策:本技能直接在的托管克隆上操作,而非在上。托管克隆位于:
mvanhorn/printing-press-library$PRESS_LIBRARY/<slug>/$PRESS_HOME/.publish-repo-$PRESS_SCOPE这与使用的克隆相同(该技能的步骤5)。复用此克隆:
/printing-press-publishbash
PUBLISH_REPO_DIR="$PRESS_HOME/.publish-repo-$PRESS_SCOPE"
PUBLISH_CONFIG="$PRESS_HOME/.publish-config-$PRESS_SCOPE.json"
if [ ! -d "$PUBLISH_REPO_DIR/.git" ]; then
# 首次设置:完整检测请参考references/library-pr-plumbing.md(通过gh api .../permissions.push检测推送/分叉权限,SSH/HTTPS协议检测,范围克隆清理循环)。
echo "Managed clone not present — bootstrapping..."
# ... (见library-pr-plumbing.md)
else
# 从上游刷新。checkout使用-f参数以丢弃上次运行在阶段4编辑和阶段7提交之间中止时留下的任何本地编辑——如果没有-f,这些未提交的更改会阻止checkout,后续的reset --hard也不会运行。
cd "$PUBLISH_REPO_DIR"
git fetch upstream main
git checkout -f main
git reset --hard upstream/main
fi托管克隆中的CLI目录为。类别已在阶段1解析(或通过查找)。
$PUBLISH_REPO_DIR/library/<category>/<slug>/find "$PUBLISH_REPO_DIR/library" -maxdepth 2 -name "<slug>" -type dbash
CLI_DIR="$PUBLISH_REPO_DIR/library/<category>/<slug>"本阶段的所有编辑均在内进行。永远不要修改——这是不同的工作副本,修改它不会流入PR。
$CLI_DIR$PRESS_LIBRARY/<slug>/Step 2 — Write the per-run plan doc
步骤2 — 编写每次运行的计划文档
Before editing code, materialize a plan markdown at:
$PRESS_MANUSCRIPTS/<slug>/<run-id>/proofs/<timestamp>-amend-<cli-name>.mdMirror to for quick reference. The plan doc carries:
/tmp/printing-press/amend/- Frontmatter: ,
date,target_cli,amend_run_id,scope_tierfindings_count - One section per active finding: id, category, classification, rationale, target files (paths), expected behavior change, test scenarios for this finding
$CLI_DIR/... - Risks and dependencies between findings (if any)
The plan is decision-shape, not execution-shape — implementer-time sequencing happens during Step 3.
在编辑代码前,生成计划markdown文件:
$PRESS_MANUSCRIPTS/<slug>/<run-id>/proofs/<timestamp>-amend-<cli-name>.md同步到以便快速参考。计划文档包含:
/tmp/printing-press/amend/- 前置元数据:、
date、target_cli、amend_run_id、scope_tierfindings_count - 每个活跃需求对应一个章节:id、类别、分类、理由、目标文件(路径)、预期行为变化、此需求的测试场景
$CLI_DIR/... - 风险和需求之间的依赖关系(如果有)
计划是决策层面的,而非执行层面的——步骤3中会进行实现者时间排序。
Step 3 — Execute the plan (with the patch contract)
步骤3 — 执行计划(遵循补丁契约)
For each finding in dependency order:
-
Edit the target files under. Honor AGENTS.md anti-reimplementation rules (no hand-rolled response builders; novel commands must call the real endpoint or read from the local store via
$CLI_DIR//// pp:client-callopt-outs only when truly justified).// pp:novel-static-reference -
Add asource comment at every changed site. Format examples:
// PATCH(<short reason>)go// PATCH(amend-2026-05-15: surface refresh-token expiry to user) — was silently retrying func (c *Client) Refresh(ctx context.Context) error { ... } -
Update. Append an entry under
$CLI_DIR/.printing-press-patches.json:patches[]json{ "date": "2026-05-15", "amend_run_id": "amend-2026-05-15T1432", "summary": "fix(superhuman): surface refresh-token expiry; add drafts new + --type sent", "files": [ "internal/auth/refresh.go", "internal/cli/drafts.go", "internal/cli/threads.go" ], "findings_addressed": ["F1", "F2", "F5", "F7"], "patch_count": <total // PATCH comments added in this run> }Both halves of the contract —source comments AND// PATCH(...)entries — are MANDATORY. The library's.printing-press-patches.jsonworkflow rejects PRs where one is present without the other. Seeverify-library-conventions"How to record a hand-edit" for the authoritative spec.~/printing-press-library/AGENTS.md -
Machine-vs-printed-CLI judgment (per AGENTS.md): when a finding's fix would generalize to every printed CLI (e.g. "the generator should emitfor any threads list command"), surface as a borderline case:
--type sent"Finding F5 (missing) looks like a machine-level fix — the generator template--type sentshould emit it for every CLI with this endpoint shape, not justinternal/generator/templates/threads.go.tmpl. Defer to a<slug>-pp-clifollow-up, or proceed CLI-specific?"/printing-press-retroWhen deferred, drop into the deferred-list with classification. When kept, add a comment in the patch noting the generalize-eventually intent.machine-level
按依赖顺序处理每个需求:
-
编辑下的目标文件。遵循AGENTS.md中的反重新实现规则(不要手动编写响应构建器;新命令必须调用真实端点或通过
$CLI_DIR//// pp:client-call仅在真正必要时从本地存储读取)。// pp:novel-static-reference -
在每个修改位置添加源码注释。格式示例:
// PATCH(<short reason>)go// PATCH(amend-2026-05-15: surface refresh-token expiry to user) — was silently retrying func (c *Client) Refresh(ctx context.Context) error { ... } -
更新。在
$CLI_DIR/.printing-press-patches.json下追加一个条目:patches[]json{ "date": "2026-05-15", "amend_run_id": "amend-2026-05-15T1432", "summary": "fix(superhuman): surface refresh-token expiry; add drafts new + --type sent", "files": [ "internal/auth/refresh.go", "internal/cli/drafts.go", "internal/cli/threads.go" ], "findings_addressed": ["F1", "F2", "F5", "F7"], "patch_count": <本次运行添加的// PATCH注释总数> }契约的两部分——源码注释AND// PATCH(...)条目——都是必须的。公共库的.printing-press-patches.json工作流会拒绝仅存在其中一部分的PR。权威规范请见verify-library-conventions中的"How to record a hand-edit"。~/printing-press-library/AGENTS.md -
机器 vs 已生成CLI的判断(遵循AGENTS.md):当某个需求的修复可推广到所有已生成CLI时(例如"生成器模板应为每个具有此端点形状的CLI生成
internal/generator/templates/threads.go.tmpl选项,而非仅--type sent"),作为边界情况展示:<slug>-pp-cli"需求F5(缺失)看起来是机器层面的修复——生成器模板--type sent应为每个具有此端点形状的CLI生成该选项,而非仅internal/generator/templates/threads.go.tmpl。是否推迟到<slug>-pp-cli后续处理,或继续针对此CLI进行修改?"/printing-press-retro如果推迟,将其添加到延迟列表,分类为。如果保留,在补丁中添加注释说明最终要推广的意图。machine-level
Step 4 — Validate
步骤4 — 验证
After all edits land, run the consolidated validator (replace with the absolute path captured at setup):
<PRINTING_PRESS_BIN>bash
<PRINTING_PRESS_BIN> publish validate --dir "$CLI_DIR" --json > /tmp/amend-validate.json
exit_code=$?publish validatego vetgo build--help--version所有编辑完成后,运行综合验证器(将替换为配置阶段捕获的绝对路径):
<PRINTING_PRESS_BIN>bash
<PRINTING_PRESS_BIN> publish validate --dir "$CLI_DIR" --json > /tmp/amend-validate.json
exit_code=$?publish validatego vetgo build--help--versionStep 5 — Retry on failure (up to 3 iterations)
步骤5 — 失败时重试(最多3次迭代)
If reports failures, parse the error categories from the JSON, attempt targeted fixes, re-run validate. Maximum 3 iterations total. After iteration 3:
publish validatebash
undefined如果报告失败,从JSON中解析错误类别,尝试针对性修复,重新运行验证。最多进行3次迭代。第3次迭代后:
publish validatebash
undefinedSave the in-progress plan + diff to a holding location
将进行中的计划 + 差异保存到临时位置
HELD_PATH="$PRESS_MANUSCRIPTS/<slug>/<run-id>/proofs/<timestamp>-amend-<cli-name>-INCOMPLETE.md"
git -C "$PUBLISH_REPO_DIR" diff > "${HELD_PATH%.md}.diff"
cp "$PLAN_PATH" "$HELD_PATH"
Surface the final error log to the user, do NOT auto-open the PR, exit. The user can resume by re-invoking the skill (Phase 1 detects the held plan and offers to resume).HELD_PATH="$PRESS_MANUSCRIPTS/<slug>/<run-id>/proofs/<timestamp>-amend-<cli-name>-INCOMPLETE.md"
git -C "$PUBLISH_REPO_DIR" diff > "${HELD_PATH%.md}.diff"
cp "$PLAN_PATH" "$HELD_PATH"
向用户展示最终错误日志,**不要**自动打开PR,退出。用户可通过重新调用技能恢复(阶段1会检测到保存的计划并提供恢复选项)。Step 6 — Caveat: validate doesn't enforce the patch contract
步骤6 — 注意事项:验证不强制执行补丁契约
publish validate.printing-press-patches.json// PATCH(...)verify-library-conventionsbash
undefinedpublish validate.printing-press-patches.json// PATCH(...)verify-library-conventionsbash
undefinedCount only NEW // PATCH(...) markers added in this run by diffing against
通过与上游差异比较,仅统计本次运行添加的新// PATCH(...)标记。对$CLI_DIR进行简单的grep -rc
也会统计之前修改运行添加的标记,这会导致当历史累计计数满足或超过本次运行声明的计数时,零新标记的运行也会通过。
grep -rcupstream. A naive grep -rc
over $CLI_DIR also counts markers added by
grep -rc—
prior amend runs, which lets a zero-new-markers run pass when prior history
—
makes the cumulative count meet or exceed the per-run declared count.
—
This check runs in Phase 4 Step 6 — BEFORE the Phase 7 commit. The edits
此检查在阶段4步骤6运行——在阶段7提交之前。编辑仍在工作树中,未提交到任何提交,因此git diff
与upstream/main比较(工作树差异)是正确的工具。format-patch upstream/main..HEAD
仅扫描已提交的历史,会发现没有提交,从而无输出——对每个有效运行都会静默返回0个标记。
git diffformat-patch upstream/main..HEADare still in the working tree, not in any commit, so git diff
against
git diff—
upstream/main (working-tree diff) is the right tool. `format-patch
—
upstream/main..HEAD` would scan committed history only, find no commits,
—
and emit nothing — silently returning 0 markers for every valid run.
—
--no-pager + --no-color + --no-ext-diff defeats colorized output and any
--no-pager + --no-color + --no-ext-diff 禁用彩色输出和任何配置的diff.external
工具,这些工具会将差异格式化为非统一差异形状,破坏grep解析。
diff.externalconfigured diff.external
tool that would reformat the diff away from
diff.external—
unified-diff shape and break the grep parse.
—
new_patch_markers=$(git -C "$PUBLISH_REPO_DIR" --no-pager diff --no-color --no-ext-diff upstream/main -- "$CLI_DIR"
| grep -cE '^+.*// PATCH(') patches_entry=$(jq '.patches[-1].patch_count // 0' "$CLI_DIR/.printing-press-patches.json") if [ "$new_patch_markers" -lt "$patches_entry" ]; then echo "ERROR: .printing-press-patches.json claims $patches_entry patch markers added this run, found $new_patch_markers new // PATCH(...) comments in the diff." exit 1 fi
| grep -cE '^+.*// PATCH(') patches_entry=$(jq '.patches[-1].patch_count // 0' "$CLI_DIR/.printing-press-patches.json") if [ "$new_patch_markers" -lt "$patches_entry" ]; then echo "ERROR: .printing-press-patches.json claims $patches_entry patch markers added this run, found $new_patch_markers new // PATCH(...) comments in the diff." exit 1 fi
Mismatched contract → fix locally before continuing. (A follow-up retro item: lift this check into `printing-press publish validate` so future amend runs catch it natively.)new_patch_markers=$(git -C "$PUBLISH_REPO_DIR" --no-pager diff --no-color --no-ext-diff upstream/main -- "$CLI_DIR"
| grep -cE '^+.*// PATCH(') patches_entry=$(jq '.patches[-1].patch_count // 0' "$CLI_DIR/.printing-press-patches.json") if [ "$new_patch_markers" -lt "$patches_entry" ]; then echo "ERROR: .printing-press-patches.json claims $patches_entry patch markers added this run, found $new_patch_markers new // PATCH(...) comments in the diff." exit 1 fi
| grep -cE '^+.*// PATCH(') patches_entry=$(jq '.patches[-1].patch_count // 0' "$CLI_DIR/.printing-press-patches.json") if [ "$new_patch_markers" -lt "$patches_entry" ]; then echo "ERROR: .printing-press-patches.json claims $patches_entry patch markers added this run, found $new_patch_markers new // PATCH(...) comments in the diff." exit 1 fi
契约不匹配→在继续前本地修复。(后续改进项:将此检查集成到`printing-press publish validate`中,以便未来的修改运行可以原生捕获此问题。)Output
输出
Phase 4 emits to Phase 5:
yaml
plan_doc_path: <path>
managed_clone_dir: <path>
cli_dir_in_clone: <path>
findings_addressed: [...]
build_status: PASS|FAIL
test_status: PASS|FAIL
dogfood_status: PASS|FAIL|N/A # PASS|FAIL when MODE=dogfood (or "both"); always N/A when MODE=direct
validate_iterations: <n>
patch_marker_count: <n>dogfood_statusMODE=dogfoodMODE=directdogfood_status=N/AMODE=both阶段4向阶段5输出:
yaml
plan_doc_path: <path>
managed_clone_dir: <path>
cli_dir_in_clone: <path>
findings_addressed: [...]
build_status: PASS|FAIL
test_status: PASS|FAIL
dogfood_status: PASS|FAIL|N/A # 当MODE=dogfood(或"both")时为PASS|FAIL;当MODE=direct时始终为N/A
validate_iterations: <n>
patch_marker_count: <n>dogfood_statusMODE=dogfoodMODE=directdogfood_status=N/AMODE=bothPhase 5 — PII Scrub
阶段5 — PII清理
Read for the full procedure. Summary:
references/pii-scrubbing.mdThe scrub has three layers, each operating on temp staging copies (NOT on the user's session transcript or the in-progress source code):
- Credentials — reuse the regex patterns from (Stripe, GitHub PATs, bearer tokens, AWS keys, etc.) plus amend-specific additions for
skills/printing-press-retro/references/secret-scrubbing.md/Authorization/Cookieheaders in hand-rolled API payloads quoted from the session transcript.X-API-Key - Entities — companies, people, emails matched against the user-maintained stop-list at . Replace with shape-preserving tokens (
~/.printing-press/amend-config.yaml,<company-1>,<person-1>) that maintain identity across the artifact set so reviewers can still parse intent.<email-1> - First-mention defense — walk each artifact for capitalized phrases that look like proper nouns and were NOT in the stop-list. Surface to the user inline before the Phase 6 PR-draft display: "Found (3x in plan doc, 1x in PR body) — add to stop-list and scrub, or accept?"
Esper Labs
Targets, in priority order: PR title/body draft, per-run plan doc, deferred-findings list, any test fixtures or example outputs newly added to . For each target, copy to BEFORE scrubbing so the user can audit what was changed.
$CLI_DIR<path>.pre-pii-scrubDefense-in-depth: walk every file in for stop-list matches. If any match is found, treat as BLOCKING — pause and require user resolution before Phase 6. The agent should never have introduced PII into Go source; this check exists to catch agent error.
*.go$CLI_DIRStop-list creation: if doesn't exist, the skill creates a default with a starter list and a comment explaining the format. File-mode validation (warn on world-writable, abort on alien-owned).
~/.printing-press/amend-config.yamlThe scrub report is written to (NOT committed; for the user's audit). The user-facing summary at the end of the phase: "X tokens replaced across Y artifacts."
$PRESS_MANUSCRIPTS/<slug>/<run-id>/scrub-report.json完整流程请阅读。流程摘要:
references/pii-scrubbing.md清理包含三层,均在临时 staging 副本上操作(不修改用户的会话记录或进行中的源代码):
- 凭证 — 复用中的正则表达式模式(Stripe、GitHub PAT、Bearer令牌、AWS密钥等),加上针对会话记录中引用的手动编写API负载里的
skills/printing-press-retro/references/secret-scrubbing.md/Authorization/Cookie头的修改专用补充规则。X-API-Key - 实体 — 匹配用户维护的阻止列表中的公司、人员、邮箱。替换为保留形状的令牌(
~/.printing-press/amend-config.yaml、<company-1>、<person-1>),这些令牌在所有产物中保持一致,以便审核者仍能解析意图。<email-1> - 首次提及防护 — 遍历每个产物,查找看起来像专有名词且不在阻止列表中的大写短语。在阶段6的PR草稿展示前在线向用户展示:"Found (计划文档中3次,PR正文中1次)——添加到阻止列表并清理,或保留?"
Esper Labs
目标优先级顺序:PR标题/正文草稿、每次运行的计划文档、延迟需求列表、中新添加的任何测试 fixture 或示例输出。对于每个目标,在清理前复制到,以便用户可以审核修改内容。
$CLI_DIR<path>.pre-pii-scrub纵深防御:遍历中的每个文件,查找阻止列表匹配项。如果找到任何匹配项,视为阻塞——暂停并要求用户解决后再进入阶段6。代理不应在Go源码中引入PII;此检查用于捕获代理错误。
$CLI_DIR*.go阻止列表创建:如果不存在,技能会创建一个包含初始列表和格式说明注释的默认文件。文件模式验证(对全局可写发出警告,对非用户所有的文件中止)。
~/.printing-press/amend-config.yaml清理报告写入(不提交;供用户审核)。阶段结束时的用户-facing摘要:"X个令牌在Y个产物中被替换。"
$PRESS_MANUSCRIPTS/<slug>/<run-id>/scrub-report.jsonPhase 6 — PR Draft Review Checkpoint (User-in-Loop #2)
阶段6 — PR草稿审核检查点(用户参与环节#2)
This is the second and final user checkpoint. Everything that follows is unattended (push + PR-open + labels + RESULT block). Show the user EVERYTHING that's about to ship before any command fires.
gh这是第二个也是最后一个用户检查点。后续所有操作均为无人值守(推送 + 打开PR + 添加标签 + RESULT块)。在任何命令执行前,向用户展示所有即将发布的内容。
ghAssemble the draft
组装草稿
Compose the PR title, body, labels, and diff summary in memory. Title format follows the public library convention:
- when the scope is bugs-only
fix(<api-slug>): <one-line summary> - when the scope includes features
feat(<api-slug>): <one-line summary> - when mixed (feature wins because it's the bigger contract change)
feat(<api-slug>): <one-line summary>
The is composed from the most important 1-3 findings (e.g. ).
<one-line summary>surface refresh-token expiry; add drafts new + --type sentPR body sections (per origin R27):
- Summary — 1-3 sentences naming the user pain and the shape of the fix
- Findings — table with ID, category, type (bug/feature), rationale
- Changes — output of
git diff --stat upstream/main..HEAD - Verification — build/test/dogfood/validate status from Phase 4
- Evidence — full GitHub URLs to the per-run plan doc and at the PR's HEAD SHA (captured AFTER push so links don't 404)
.printing-press-patches.json - Closes #N footer when an issue match was found in Step 6 of
library-pr-plumbing.md
Labels: always; for bugs-only scope, for bugs+features, for all-tiers.
comp:<api-slug>priority:P1priority:P2priority:P3在内存中组合PR标题、正文、标签和差异摘要。标题格式遵循公共库约定:
- 当范围仅为bugs时:
fix(<api-slug>): <一行摘要> - 当范围包含features时:
feat(<api-slug>): <一行摘要> - 混合范围时:(feature优先,因为它是更大的契约变更)
feat(<api-slug>): <一行摘要>
<一行摘要>surface refresh-token expiry; add drafts new + --type sentPR正文章节(遵循origin R27):
- 摘要 — 1-3句话,说明用户痛点和修复形式
- 需求 — 表格,包含ID、类别、类型(bug/feature)、理由
- 变更 — 的输出
git diff --stat upstream/main..HEAD - 验证 — 阶段4的构建/测试/dogfood/验证状态
- 证据 — PR的HEAD SHA对应的每次运行计划文档和的完整GitHub URL(推送后捕获,避免链接404)
.printing-press-patches.json - Closes #N页脚,当在步骤6中找到匹配的issue时
library-pr-plumbing.md
标签:始终添加;仅bugs范围添加,bugs+features范围添加,所有层级范围添加。
comp:<api-slug>priority:P1priority:P2priority:P3Display before gh fires
在gh命令执行前展示
Show the user the title, body, label list, and . If Phase 5 surfaced unrecognized capitalized phrases that the user accepted as legitimate, RE-DISPLAY those inline now with the sentence each appears in:
git diff --stat"Reminder: PR body references(you accepted as legitimate during Phase 5). Confirm before opening."<phrase>
向用户展示标题、正文、标签列表和。如果阶段5发现未识别的大写短语且用户确认保留合法,现在重新内联展示这些短语及其出现的句子:
git diff --stat"提醒:PR正文引用了(你在阶段5确认保留合法)。打开前请确认。"<phrase>
AskUserQuestion: open / edit / hold / abort
AskUserQuestion: 打开 / 编辑 / 保存 / 中止
PR draft ready. What now?
1. Open PR as drafted (recommended)
2. Edit then open — drop into an interactive review of title/body
3. Hold — save plan + diff for later resume; nothing pushed
4. Abort — discard everything, no record keptFor edit then open: present the title and body as separate editable blocks, accept the user's revisions, re-display the full draft, confirm before proceeding.
For hold: save the plan + diff to and . Emit a RESULT block with and the resume path. A future run can detect held files and offer to resume.
$PRESS_MANUSCRIPTS/<slug>/<run-id>/proofs/<timestamp>-amend-<cli-name>-HELD.md${path%.md}.diffstatus: held/printing-press-amendFor abort: emit a brief confirmation. Plan doc from U5 stays (with written into the frontmatter) so the user has a record of what was found, but nothing else is preserved. Managed clone is reset on next run.
status: abortedPR草稿已准备好。下一步?
1. 按草稿打开PR(推荐)
2. 编辑后打开——进入标题/正文的交互式审核
3. 保存——保存计划 + 差异供以后恢复;不推送任何内容
4. 中止——丢弃所有内容,不保留记录对于编辑后打开:将标题和正文作为单独的可编辑块展示,接受用户的修订,重新展示完整草稿,确认后继续。
对于保存:将计划 + 差异保存到和。输出RESULT块,包含和恢复路径。未来的运行可以检测到保存的文件并提供恢复选项。
$PRESS_MANUSCRIPTS/<slug>/<run-id>/proofs/<timestamp>-amend-<cli-name>-HELD.md${path%.md}.diffstatus: held/printing-press-amend对于中止:输出简短确认。U5的计划文档会保留(前置元数据中写入),以便用户有记录,但不保留其他内容。托管克隆会在下次运行时重置。
status: abortedPhase 7 — PR Open (Autonomous)
阶段7 — 打开PR(自主运行)
If the user picked open or edit-then-open, run Steps 5-7:
references/library-pr-plumbing.md- Step 5 — + commit with conventional message + the findings list
git add "$CLI_DIR" - Step 6 — search for an existing issue matching the findings; link or open new; self-assign best-effort
- Step 7 — push the branch (push-vs-fork access mode determined in Step 1), with
gh pr create, capture HEAD_SHA, apply labels--body-file
The fork/access detection, branch collision handling, and managed-clone refresh patterns are documented in detail in . Do NOT inline those patterns here — the reference is the authoritative source.
references/library-pr-plumbing.mdAfter the PR opens, surface the URL + Greptile note in the user-facing summary:
"PR open: <url>Greptile will review within ~2 minutes. Check inline comments:gh api repos/mvanhorn/printing-press-library/pulls/<N>/commentsP0/P1 findings are worth addressing before requesting human review."
如果用户选择打开或编辑后打开,运行步骤5-7:
references/library-pr-plumbing.md- 步骤5 — + 符合约定的提交消息 + 需求列表
git add "$CLI_DIR" - 步骤6 — 搜索与需求匹配的现有issue;链接或打开新issue;尽最大努力自分配
- 步骤7 — 推送分支(推送/分叉访问模式在步骤1中确定),使用
gh pr create,捕获HEAD_SHA,应用标签--body-file
分叉/访问检测、分支冲突处理和托管克隆刷新模式在中有详细记录。不要在此处内联这些模式——参考文档是权威来源。
references/library-pr-plumbing.mdPR打开后,在用户-facing摘要中展示URL + Greptile说明:
"PR已打开:<url>Greptile将在约2分钟内审核。请查看内联评论:gh api repos/mvanhorn/printing-press-library/pulls/<N>/comments在请求人工审核前,建议解决P0/P1需求。"
Phase 8 — Output
阶段8 — 输出
Emit the structured block on completion. Format:
---PATCH-RESULT------PATCH-RESULT---
pr_url: <url>
pr_number: <n>
branch_name: <name>
api_slug: <slug>
scope_tier: <bugs|bugs+features|all|custom>
files_changed:
- <file>
build_status: <PASS|FAIL>
test_status: <PASS|FAIL>
dogfood_status: <PASS|FAIL|N/A>
pii_scrub_summary: <N tokens replaced across M artifacts>
findings_addressed:
- <one-line-summary>
findings_deferred:
- <one-line-summary>
deferred_list_path: <path>
plan_doc_path: <path>
---END-PATCH-RESULT---完成后输出结构化的块。格式:
---PATCH-RESULT------PATCH-RESULT---
pr_url: <url>
pr_number: <n>
branch_name: <name>
api_slug: <slug>
scope_tier: <bugs|bugs+features|all|custom>
files_changed:
- <file>
build_status: <PASS|FAIL>
test_status: <PASS|FAIL>
dogfood_status: <PASS|FAIL|N/A>
pii_scrub_summary: <N tokens replaced across M artifacts>
findings_addressed:
- <一行摘要>
findings_deferred:
- <一行摘要>
deferred_list_path: <path>
plan_doc_path: <path>
---END-PATCH-RESULT---Verification of this skill itself
本技能自身的验证
The static lint pass for this SKILL.md runs via:
bash
<PRINTING_PRESS_BIN> verify-internal-skill --dir skills/printing-press-amend(See and the matching test file. The setup-contract parity check runs as a Go test in — .)
internal/cli/verify_internal_skill.gointernal/pipeline/contracts_test.goTestSkillSetupBlocksMatchWorkspaceContract本SKILL.md的静态 lint 检查通过以下命令运行:
bash
<PRINTING_PRESS_BIN> verify-internal-skill --dir skills/printing-press-amend(见和对应的测试文件。配置合约一致性检查作为Go测试在中运行——。)
internal/cli/verify_internal_skill.gointernal/pipeline/contracts_test.goTestSkillSetupBlocksMatchWorkspaceContract