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/superhuman
This skill lives in this repo (the machine) and acts on a printed CLI in the public library. It is sibling to
/printing-press-publish
(adds a new CLI),
/printing-press-polish
(improves a CLI pre-publish), and
/printing-press-retro
(reflects on the machine itself). None of those cover post-publish CLI amendments driven by real-session friction.
The artifact this skill produces is semantically a "patch" (in the git/PR sense), tracked by the public library's
// PATCH(...)
source-comment convention and
.printing-press-patches.json
manifest. The slash-skill name is
amend
to disambiguate from the existing
printing-press patch
binary subcommand (which AST-injects pre-defined features — different mechanism, different intent).
将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。它是
/printing-press-publish
(添加新CLI)、
/printing-press-polish
(发布前优化CLI)和
/printing-press-retro
(反思机器本身)的同类技能。上述技能均不支持由真实会话痛点驱动的发布后CLI修改。
本技能生成的产物在语义上是一个“补丁”(符合git/PR定义),通过公共库的
// PATCH(...)
源码注释约定和
.printing-press-patches.json
清单进行追踪。斜杠技能命名为
amend
,以区分现有的
printing-press patch
二进制子命令(该命令通过AST注入预定义功能——机制和意图均不同)。

Setup

配置

Before doing anything else:
<!-- PRESS_SETUP_CONTRACT_START -->
bash
undefined
在执行任何操作前:
<!-- PRESS_SETUP_CONTRACT_START -->
bash
undefined

min-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-press
invocation.
export PATH
above only affects this one

Bash tool call; subsequent calls open a fresh shell and resolve bare

printing-press
against the user's default PATH, where a stale global

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:
  • MODE=direct
    — the prompt contains a concrete CLI name AND at least one direct-input signal:
    • Action verbs targeting the CLI:
      rename
      ,
      add
      ,
      remove
      ,
      fix
      ,
      sniff
      ,
      discover
    • 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"
  • MODE=dogfood
    — 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=both
    — 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")
  • 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?
    1. Mine the current session transcript (dogfood mode)
    2. Use the asks I just typed (direct-input mode)
    3. Both — combine transcript friction with my asks"
Default when no slash-command prompt is present at all:
MODE=dogfood
. This preserves the canonical UX —
/printing-press-amend
with nothing after still works exactly as it did in v0.1.
读取斜杠命令提示符内容和对话上下文的即时调用回合。分为以下四个分支:
  • MODE=direct
    — 提示符包含具体的CLI名称AND至少一个直接输入信号:
    • 针对CLI的动作动词:
      rename
      add
      remove
      fix
      sniff
      discover
    • 用户想要添加的明确URL(例如
      https://example.com/feed/x
    • 数据源、命令、端点或功能的枚举列表
    • 类似"these ideas"、"these features"、"with the following"的表述
  • MODE=dogfood
    — 提示符为空,OR仅指定CLI名称而无需求("amend the superhuman CLI"),OR明确引用会话("what I just dogfooded"、"this session's friction"、"from my session today")
  • MODE=both
    — 提示符明确同时引用会话和特定需求("I dogfooded this session and also want to add feature X"、"in addition to the friction I hit, please add command Y")
  • 模糊场景 — 仅存在一种信号(指定CLI但无动词,或有动词但无目标CLI,或需求表述既可视为痛点报告也可视为新需求)。通过
    AskUserQuestion
    询问用户:
    "有两种方式为本次修改获取需求,请问哪种符合你的情况?
    1. 挖掘当前会话记录(dogfood模式)
    2. 使用我刚刚输入的需求(直接输入模式)
    3. 两者结合——将会话痛点与我的需求合并"
当完全没有斜杠命令提示符时,默认使用
MODE=dogfood
。这保留了标准用户体验——
/printing-press-amend
不带任何参数时的行为与v0.1版本完全一致。

Persist the mode

持久化模式

Write the resolved mode to
$PRESS_RUNSTATE/current/mode.txt
so later phases (and a resumed run) can read it:
bash
echo "$MODE" > "$PRESS_RUNSTATE/current/mode.txt"
将解析后的模式写入
$PRESS_RUNSTATE/current/mode.txt
,以便后续阶段(以及恢复的运行)可以读取:
bash
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
### 1a
, direct-input findings flow through
### 1b
, and combined runs execute both sub-sections in sequence. Phase 2 onward ignores the mode entirely — the finding list is the contract.
阶段0向阶段1输出一行内容:
yaml
mode: <dogfood|direct|both>
阶段1根据该值分支处理——dogfood需求通过
### 1a
流程,直接输入需求通过
### 1b
流程,合并模式则依次执行两个子流程。阶段2及以后完全忽略模式——需求列表是唯一的契约。

Phase 1 — Capture

阶段1 — 捕获需求

This phase produces a typed finding list. The list shape is identical across modes: each finding carries
id
,
kind
,
category
,
classification
(bug or feature),
evidence
,
target_cli
,
rationale
, and
provenance
(
transcript
for dogfood,
user-ask
for direct,
sniff
for sniff-derived). Phase 2 consumes the list verbatim.
When
MODE=dogfood
, run only
### 1a
. When
MODE=direct
, run only
### 1b
. When
MODE=both
, run
### 1a
first, then
### 1b
, and merge the two finding lists with non-colliding IDs (1b continues numbering where 1a left off).
本阶段生成结构化需求列表。所有模式下的列表格式相同:每个需求包含
id
kind
category
classification
(bug或feature)、
evidence
target_cli
rationale
provenance
(dogfood模式为
transcript
,直接输入模式为
user-ask
,探测衍生为
sniff
)。阶段2会直接使用该列表。
MODE=dogfood
时,仅运行
### 1a
。当
MODE=direct
时,仅运行
### 1b
。当
MODE=both
时,先运行
### 1a
,再运行
### 1b
,并合并两个需求列表,确保ID不冲突(1b的ID从1a结束的编号开始)。

1a. Dogfood mode (MODE=dogfood)

1a. Dogfood模式(MODE=dogfood)

Read
references/transcript-parsing.md
for the full procedure. Summary of what this sub-section does:
  1. Resolve the active session transcript file — derive
    <project-dir-slug>
    from the current working directory, list
    ~/.claude/projects/<slug>/*.jsonl
    by mtime, pick the most-recently-modified. ALWAYS confirm the resolved path with the user via
    AskUserQuestion
    before reading — wrong-file selection ingests friction from the wrong session.
  2. Walk the transcript and extract friction signals — non-zero exit codes, error messages, hand-rolled API payloads (e.g. direct
    curl
    POSTs 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
    <slug>-pp-cli
    it references.
  3. 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.
  4. Auto-detect target CLI — count occurrences of each
    <slug>-pp-cli
    in the signals, propose the most-touched CLI as the default. Confirm with
    AskUserQuestion
    (single CLI: simple yes/no; multiple close: pick from list). When the user passed an explicit
    <cli-name-or-path>
    argument, skip auto-detect.
  5. Resolve target paths — accept short name, full name, or absolute path (per R4). Look up the public-library category by walking
    ~/printing-press-library/library/*/
    for 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.
Each finding emitted by 1a carries
provenance: transcript
. Output flows into Phase 2 as the structured finding list documented in
references/transcript-parsing.md
.
完整流程请阅读
references/transcript-parsing.md
。本小节流程摘要:
  1. 解析当前会话记录文件 — 从当前工作目录派生
    <project-dir-slug>
    ,按修改时间列出
    ~/.claude/projects/<slug>/*.jsonl
    ,选择最新修改的文件。读取前必须通过
    AskUserQuestion
    与用户确认解析后的路径
    ——选择错误文件会引入错误会话的痛点。
  2. 遍历会话记录并提取痛点信号 — 非零退出码、错误消息、手动编写的API负载(例如应使用CLI命令而直接调用的
    curl
    POST请求)、失败后重试模式、代理注释如"X不存在" / "X返回400"、缺失标志位引用、静默返回空值、认证困惑。每个信号包含时间戳 + 类别 + 原文证据 + 引用的
    <slug>-pp-cli
  3. 将每个信号分类为bug或feature,并附上一行理由。Bug = CLI行为错误;feature = CLI缺少某项功能。分类是代理的最佳判断;用户会在U4范围检查点确认或覆盖。
  4. 自动检测目标CLI — 统计每个
    <slug>-pp-cli
    在信号中的出现次数,将出现最频繁的CLI作为默认建议。通过
    AskUserQuestion
    确认(单个CLI:简单是/否;多个相近选项:从列表中选择)。当用户传入了明确的
    <cli-name-or-path>
    参数时,跳过自动检测。
  5. 解析目标路径 — 接受短名称、完整名称或绝对路径(遵循R4规则)。通过遍历
    ~/printing-press-library/library/*/
    查找匹配目录,确定公共库类别。该类别在U7的PR提交阶段需要用到,因此在此处捕获以避免重复解析。
1a生成的每个需求均带有
provenance: transcript
。输出作为结构化需求列表流入阶段2,格式参考
references/transcript-parsing.md

1b. Direct-input mode (MODE=direct)

1b. 直接输入模式(MODE=direct)

Read
references/direct-input-parsing.md
for the full procedure (introduced in v0.2). Summary of what this sub-section does:
  1. 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.
  2. 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 (
    <slug>-pp-cli
    or "the <slug> CLI"); if absent, ask the user.
  3. Parse the asks into structured findings using the rubric in
    references/direct-input-parsing.md
    . Each ask maps to one finding with a typed
    kind
    field:
    • rename
      — "rename X to Y" / "call it X instead of Y" →
      classification: feature
    • add-command
      — "add command X" / "add subcommand X" →
      classification: feature
    • add-feed
      — "add feed <url>" / enumerated URLs the user wants added (one finding per URL) →
      classification: feature
    • add-endpoint
      — "add endpoint <url>" / explicit API path →
      classification: feature
    • fix-bug
      — "fix X" / "X is broken" / "X returns null" →
      classification: bug
    • sniff
      — "sniff for new APIs" / "find new endpoints" / "discover more" → routes to the sniff subroutine in
      ### 1b.i
  4. Each finding records the user's verbatim phrasing in
    evidence
    so the U4 scope confirmation modal shows the user what they actually wrote.
  5. Edge cases — multi-CLI asks split into two separate runs (out of scope for v0.2; ask the user to pick one). Ambiguous verbs (
    update X
    without specifics) trigger an
    AskUserQuestion
    clarification rather than a guess.
Each finding emitted by 1b carries
provenance: user-ask
(or
provenance: sniff
for findings produced by the sniff subroutine). Output flows into Phase 2 as the same structured finding list shape used by 1a.
完整流程请阅读
references/direct-input-parsing.md
(v0.2版本引入)。本小节流程摘要:
  1. 读取斜杠命令提示符内容以及触发技能的即时代理消息回合——这些包含用户的原始需求(例如"rename Digg 1000 to Digg, add these four feeds: ..., sniff for new endpoints")。无需确认会话记录;跳过1a中运行的U1会话路径弹窗。
  2. 解析目标CLI — 与1a步骤4-5使用相同的名称解析规则(遵循R4),但CLI通常已在提示符中指定。通过正则表达式提取(
    <slug>-pp-cli
    或"the <slug> CLI");如果未找到,询问用户。
  3. 将需求解析为结构化需求,使用
    references/direct-input-parsing.md
    中的规则。每个需求映射为一个带有
    kind
    字段的结构化条目:
    • rename
      — "rename X to Y" / "call it X instead of Y" →
      classification: feature
    • add-command
      — "add command X" / "add subcommand X" →
      classification: feature
    • add-feed
      — "add feed <url>" / 用户想要添加的枚举URL(每个URL对应一个需求)→
      classification: feature
    • add-endpoint
      — "add endpoint <url>" / 明确的API路径 →
      classification: feature
    • fix-bug
      — "fix X" / "X is broken" / "X returns null" →
      classification: bug
    • sniff
      — "sniff for new APIs" / "find new endpoints" / "discover more" → 路由到
      ### 1b.i
      中的探测子流程
  4. 每个需求记录用户的原始表述
    evidence
    字段中,以便U4范围确认弹窗显示用户实际输入的内容。
  5. 边缘情况 — 多CLI需求拆分为两个独立运行(v0.2版本暂不支持;请用户选择一个)。模糊动词(无具体内容的
    update X
    )触发
    AskUserQuestion
    澄清,而非猜测。
1b生成的每个需求均带有
provenance: user-ask
(或由探测子流程生成的需求带有
provenance: sniff
)。输出作为与1a相同格式的结构化需求列表流入阶段2。

1b.i. Sniff-finding subroutine

1b.i. 探测需求子流程

Triggered when the parsing rubric tags any 1b ask as
kind: sniff
(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.
Step 1 — Resolve the target source URL. Read the target CLI's published manifest at
~/printing-press-library/library/<category>/<slug>/.printing-press.json
and extract
source_url
(or
spec_url
as fallback). Category was resolved in 1b step 2.
If 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
<PRINTING_PRESS_BIN>
with the absolute path captured at setup:
bash
<PRINTING_PRESS_BIN> crowd-sniff --site "$SOURCE_URL" --json > /tmp/amend-sniff-crowd.json
crowd_exit=$?
crowd-sniff
queries npm SDKs and GitHub code search to discover candidate endpoints — no browser required. Typical runtime is under a minute.
Step 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:
  • id: F<n>
    (next available number after the parsed asks)
  • kind: add-endpoint
  • classification: feature
  • evidence: "discovered via crowd-sniff: <endpoint-path>"
    (or
    browser-sniff
    when applicable)
  • target_cli: <slug>-pp-cli
  • rationale: <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.
ConditionBehavior
.printing-press.json
lacks
source_url
AND user skips when asked
Drop sniff finding; continue with other 1b findings; log "sniff skipped — no source URL".
crowd-sniff
exits non-zero
Log the error; skip sniff findings; continue with other 1b findings. Do NOT abort the amend run.
crowd-sniff
returns zero candidate endpoints
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 availableLog; 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
(sniff)
provenance tag so the user can decide whether to keep them as a group, e.g.:
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需求标记为
kind: sniff
时触发(例如"sniff for new APIs"、"find new endpoints"、"discover more endpoints in <site>"等表述)。探测是每次运行的可选功能——仅当用户明确指定时才会调用。当没有探测需求时,完全跳过本子流程。
步骤1 — 解析目标源URL。读取目标CLI在
~/printing-press-library/library/<category>/<slug>/.printing-press.json
中的已发布清单,提取
source_url
(或
spec_url
作为备选)。类别已在1b步骤2中解析。
如果两个字段均未设置,在线询问用户:
"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
查询npm SDK和GitHub代码搜索以发现候选端点——无需浏览器。典型运行时间不到一分钟。
步骤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-endpoint
  • classification: feature
  • evidence: "discovered via crowd-sniff: <endpoint-path>"
    (或适用时为
    browser-sniff
  • target_cli: <slug>-pp-cli
  • rationale: <探测输出中的一行摘要(如果有),否则为"sniff candidate, user to confirm">
  • provenance: sniff
默认在阶段3将这些需求归类为Tier 3(优化/架构)——用户会进行审核,并可将个别条目提升为Tier 2(高优先级)。
步骤5 — 降级路径
条件行为
.printing-press.json
缺少
source_url
且用户跳过询问
移除探测需求;继续处理其他1b需求;记录"sniff skipped — no source URL"。
crowd-sniff
非零退出
记录错误;跳过探测需求;继续处理其他1b需求。不要中止修改运行
crowd-sniff
未返回候选端点
向延迟需求列表添加一个条目("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
mvanhorn/printing-press-library
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.
bash
undefined
对于阶段1的每个需求,在
mvanhorn/printing-press-library
的开放+最近合并PR中搜索匹配项。重复检测标准(按优先级排序):(1) 目标CLI的目录路径与PR的变更文件列表重叠,(2) 需求类别+理由中的关键词与PR标题或正文匹配。
bash
undefined

Replace <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
gh pr list --repo mvanhorn/printing-press-library
--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

可移植计算"90天前"的日期——
date -v-90d
仅适用于BSD/macOS,
date -d
仅适用于GNU/Linux。先尝试GNU格式,再尝试BSD格式,最后尝试python3。如果所有格式均失败,明确错误中止,而非让去重守卫因空的
merged:>
限定符而静默退出。

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.

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
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

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
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

对于每个可能存在重复匹配的需求,在线展示:

> "需求`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
.printing-press.json
for the target CLI to find the published version. Compare to what the local printed CLI binary reports.
bash
undefined
读取目标CLI在公共库中的
.printing-press.json
以查找已发布版本。与本地已生成的CLI二进制版本进行比较。
bash
undefined

Read 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
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

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
    classification: bug
    . CLI behavior is wrong; fixes restore correctness.
  • Tier 2 — Missing features that solve immediate session pain
    classification: feature
    findings tied to a hand-rolled workaround the user actually built during the session (i.e. the user clearly needed it now, not theoretically).
  • Tier 3 — Polish / architecture — remaining
    classification: feature
    findings that are nice-to-have or architectural improvements without an immediate workaround in the session.
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 — 所有
    classification: bug
    的需求。CLI行为错误;修复可恢复正确性。
  • 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 findings
The
AskUserQuestion
options must be self-contained (each label must convey what it does without relying on description text — some harnesses hide the description).
For 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.md
The
<run-id>
is a fresh timestamped id for this amend run (e.g.
amend-2026-05-15T1432
). Format the deferred file as a YAML preamble + a finding-per-section markdown body so a future
/printing-press-amend
run on the same CLI can re-surface the items.
yaml
---
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: unknown
.
On a subsequent
/printing-press-amend
run, Phase 3 should look in
$PRESS_MANUSCRIPTS/<api-slug>/
for the most-recent
*-deferred.md
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.)
对于每个未包含在确认范围内的需求,追加到延迟列表markdown文件:
$PRESS_MANUSCRIPTS/<api-slug>/<run-id>/proofs/<timestamp>-amend-<cli-name>-deferred.md
<run-id>
是本次修改运行的全新时间戳ID(例如
amend-2026-05-15T1432
)。将延迟文件格式化为YAML前置元数据 + 每个需求对应一个章节的markdown正文,以便未来针对同一CLI的
/printing-press-amend
运行可以重新展示这些条目。
yaml
---
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
在后续的
/printing-press-amend
运行中,阶段3应在
$PRESS_MANUSCRIPTS/<api-slug>/
中查找最新的
*-deferred.md
文件,并向用户提供选项,将任何仍相关的条目包含在本次运行的范围内。(实现说明:此重新展示逻辑在v0.1版本发布;不要静默重新添加——始终展示并确认。)

Edge 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
mvanhorn/printing-press-library
rather than on
$PRESS_LIBRARY/<slug>/
. The managed clone is at:
$PRESS_HOME/.publish-repo-$PRESS_SCOPE
This is the same clone
/printing-press-publish
uses (Step 5 of that skill). Reuse it:
bash
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
fi
The CLI's directory inside the managed clone is
$PUBLISH_REPO_DIR/library/<category>/<slug>/
. The category was resolved in Phase 1 (or look it up with
find "$PUBLISH_REPO_DIR/library" -maxdepth 2 -name "<slug>" -type d
).
bash
CLI_DIR="$PUBLISH_REPO_DIR/library/<category>/<slug>"
All edits in this phase happen INSIDE
$CLI_DIR
. Never touch
$PRESS_LIBRARY/<slug>/
— that's a different working copy and editing it would not flow to the PR.
根据计划中的预实现决策:本技能直接
mvanhorn/printing-press-library
的托管克隆上操作,而非在
$PRESS_LIBRARY/<slug>/
上。托管克隆位于:
$PRESS_HOME/.publish-repo-$PRESS_SCOPE
这与
/printing-press-publish
使用的克隆相同(该技能的步骤5)。复用此克隆:
bash
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目录为
$PUBLISH_REPO_DIR/library/<category>/<slug>/
。类别已在阶段1解析(或通过
find "$PUBLISH_REPO_DIR/library" -maxdepth 2 -name "<slug>" -type d
查找)。
bash
CLI_DIR="$PUBLISH_REPO_DIR/library/<category>/<slug>"
本阶段的所有编辑均在
$CLI_DIR
内进行。永远不要修改
$PRESS_LIBRARY/<slug>/
——这是不同的工作副本,修改它不会流入PR。

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>.md
Mirror to
/tmp/printing-press/amend/
for quick reference. The plan doc carries:
  • Frontmatter:
    date
    ,
    target_cli
    ,
    amend_run_id
    ,
    scope_tier
    ,
    findings_count
  • One section per active finding: id, category, classification, rationale, target files (
    $CLI_DIR/...
    paths), expected behavior change, test scenarios for this finding
  • 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_tier
    findings_count
  • 每个活跃需求对应一个章节:id、类别、分类、理由、目标文件(
    $CLI_DIR/...
    路径)、预期行为变化、此需求的测试场景
  • 风险和需求之间的依赖关系(如果有)
计划是决策层面的,而非执行层面的——步骤3中会进行实现者时间排序。

Step 3 — Execute the plan (with the patch contract)

步骤3 — 执行计划(遵循补丁契约)

For each finding in dependency order:
  1. Edit the target files under
    $CLI_DIR/
    . 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
    // pp:client-call
    /
    // pp:novel-static-reference
    opt-outs only when truly justified).
  2. Add a
    // PATCH(<short reason>)
    source comment at every changed site. Format examples:
    go
    // PATCH(amend-2026-05-15: surface refresh-token expiry to user) — was silently retrying
    func (c *Client) Refresh(ctx context.Context) error {
        ...
    }
  3. Update
    $CLI_DIR/.printing-press-patches.json
    . Append an entry under
    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 —
    // PATCH(...)
    source comments AND
    .printing-press-patches.json
    entries — are MANDATORY. The library's
    verify-library-conventions
    workflow rejects PRs where one is present without the other. See
    ~/printing-press-library/AGENTS.md
    "How to record a hand-edit" for the authoritative spec.
  4. Machine-vs-printed-CLI judgment (per AGENTS.md): when a finding's fix would generalize to every printed CLI (e.g. "the generator should emit
    --type sent
    for any threads list command"), surface as a borderline case:
    "Finding F5 (
    --type sent
    missing) looks like a machine-level fix — the generator template
    internal/generator/templates/threads.go.tmpl
    should emit it for every CLI with this endpoint shape, not just
    <slug>-pp-cli
    . Defer to a
    /printing-press-retro
    follow-up, or proceed CLI-specific?"
    When deferred, drop into the deferred-list with classification
    machine-level
    . When kept, add a comment in the patch noting the generalize-eventually intent.
按依赖顺序处理每个需求:
  1. 编辑
    $CLI_DIR/
    下的目标文件。遵循AGENTS.md中的反重新实现规则(不要手动编写响应构建器;新命令必须调用真实端点或通过
    // pp:client-call
    /
    // pp:novel-static-reference
    仅在真正必要时从本地存储读取)。
  2. 在每个修改位置添加
    // 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 {
        ...
    }
  3. 更新
    $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注释总数>
    }
    契约的两部分——
    // PATCH(...)
    源码注释AND
    .printing-press-patches.json
    条目——都是必须的。公共库的
    verify-library-conventions
    工作流会拒绝仅存在其中一部分的PR。权威规范请见
    ~/printing-press-library/AGENTS.md
    中的"How to record a hand-edit"。
  4. 机器 vs 已生成CLI的判断(遵循AGENTS.md):当某个需求的修复可推广到所有已生成CLI时(例如"生成器模板
    internal/generator/templates/threads.go.tmpl
    应为每个具有此端点形状的CLI生成
    --type sent
    选项,而非仅
    <slug>-pp-cli
    "),作为边界情况展示:
    "需求F5(缺失
    --type sent
    )看起来是机器层面的修复——生成器模板
    internal/generator/templates/threads.go.tmpl
    应为每个具有此端点形状的CLI生成该选项,而非仅
    <slug>-pp-cli
    。是否推迟到
    /printing-press-retro
    后续处理,或继续针对此CLI进行修改?"
    如果推迟,将其添加到延迟列表,分类为
    machine-level
    。如果保留,在补丁中添加注释说明最终要推广的意图。

Step 4 — Validate

步骤4 — 验证

After all edits land, run the consolidated validator (replace
<PRINTING_PRESS_BIN>
with the absolute path captured at setup):
bash
<PRINTING_PRESS_BIN> publish validate --dir "$CLI_DIR" --json > /tmp/amend-validate.json
exit_code=$?
publish validate
runs manifest, phase5, govulncheck (scoped to this CLI's module),
go vet
,
go build
,
--help
,
--version
. Exit 0 = clean.
所有编辑完成后,运行综合验证器(将
<PRINTING_PRESS_BIN>
替换为配置阶段捕获的绝对路径):
bash
<PRINTING_PRESS_BIN> publish validate --dir "$CLI_DIR" --json > /tmp/amend-validate.json
exit_code=$?
publish validate
会运行清单验证、phase5验证、govulncheck(针对此CLI的模块)、
go vet
go build
--help
--version
。退出码0表示验证通过。

Step 5 — Retry on failure (up to 3 iterations)

步骤5 — 失败时重试(最多3次迭代)

If
publish validate
reports failures, parse the error categories from the JSON, attempt targeted fixes, re-run validate. Maximum 3 iterations total. After iteration 3:
bash
undefined
如果
publish validate
报告失败,从JSON中解析错误类别,尝试针对性修复,重新运行验证。最多进行3次迭代。第3次迭代后:
bash
undefined

Save 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
does NOT check
.printing-press-patches.json
// PATCH(...)
parity. That contract is enforced by the public library's
verify-library-conventions
workflow only after the PR opens. To catch it locally, run a quick parity check before proceeding to Phase 5:
bash
undefined
publish validate
检查
.printing-press-patches.json
// PATCH(...)
的一致性。该契约仅在PR打开后由公共库的
verify-library-conventions
工作流强制执行。为了在本地捕获此问题,在进入阶段5前运行快速一致性检查:
bash
undefined

Count only NEW // PATCH(...) markers added in this run by diffing against

通过与上游差异比较,仅统计本次运行添加的新// PATCH(...)标记。对$CLI_DIR进行简单的
grep -rc
也会统计之前修改运行添加的标记,这会导致当历史累计计数满足或超过本次运行声明的计数时,零新标记的运行也会通过。

upstream. A naive
grep -rc
over $CLI_DIR also counts markers added by

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个标记。

are still in the working tree, not in any commit, so
git diff
against

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解析。

configured
diff.external
tool that would reformat the diff away from

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

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

契约不匹配→在继续前本地修复。(后续改进项:将此检查集成到`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_status
per mode.
When
MODE=dogfood
, the value reflects the result of the dogfood validation step that consumed the transcript-derived findings (PASS if the run produced a clean fix, FAIL if it surfaced a regression). When
MODE=direct
, there is no transcript to dogfood against — set
dogfood_status=N/A
. When
MODE=both
, dogfood validation still runs against the transcript half of the findings; set PASS/FAIL accordingly. This default must be set at the latest by the end of Phase 4 so Phase 7's PR body and Phase 8's RESULT block never emit an empty value.
阶段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_status
按模式区分
。当
MODE=dogfood
时,该值反映针对会话衍生需求的dogfood验证步骤结果(如果运行生成了干净的修复则为PASS,如果出现回归则为FAIL)。当
MODE=direct
时,没有会话可进行dogfood验证——设置
dogfood_status=N/A
。当
MODE=both
时,仍会针对会话部分的需求运行dogfood验证;相应设置PASS/FAIL。必须在阶段4结束前设置此默认值,以便阶段7的PR正文和阶段8的RESULT块永远不会输出空值。

Phase 5 — PII Scrub

阶段5 — PII清理

Read
references/pii-scrubbing.md
for the full procedure. Summary:
The scrub has three layers, each operating on temp staging copies (NOT on the user's session transcript or the in-progress source code):
  1. Credentials — reuse the regex patterns from
    skills/printing-press-retro/references/secret-scrubbing.md
    (Stripe, GitHub PATs, bearer tokens, AWS keys, etc.) plus amend-specific additions for
    Authorization
    /
    Cookie
    /
    X-API-Key
    headers in hand-rolled API payloads quoted from the session transcript.
  2. Entities — companies, people, emails matched against the user-maintained stop-list at
    ~/.printing-press/amend-config.yaml
    . Replace with shape-preserving tokens (
    <company-1>
    ,
    <person-1>
    ,
    <email-1>
    ) that maintain identity across the artifact set so reviewers can still parse intent.
  3. 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
    Esper Labs
    (3x in plan doc, 1x in PR body) — add to stop-list and scrub, or accept?"
Targets, in priority order: PR title/body draft, per-run plan doc, deferred-findings list, any test fixtures or example outputs newly added to
$CLI_DIR
. For each target, copy to
<path>.pre-pii-scrub
BEFORE scrubbing so the user can audit what was changed.
Defense-in-depth: walk every
*.go
file in
$CLI_DIR
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.
Stop-list creation: if
~/.printing-press/amend-config.yaml
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).
The scrub report is written to
$PRESS_MANUSCRIPTS/<slug>/<run-id>/scrub-report.json
(NOT committed; for the user's audit). The user-facing summary at the end of the phase: "X tokens replaced across Y artifacts."
完整流程请阅读
references/pii-scrubbing.md
。流程摘要:
清理包含三层,均在临时 staging 副本上操作(修改用户的会话记录或进行中的源代码):
  1. 凭证 — 复用
    skills/printing-press-retro/references/secret-scrubbing.md
    中的正则表达式模式(Stripe、GitHub PAT、Bearer令牌、AWS密钥等),加上针对会话记录中引用的手动编写API负载里的
    Authorization
    /
    Cookie
    /
    X-API-Key
    头的修改专用补充规则。
  2. 实体 — 匹配用户维护的
    ~/.printing-press/amend-config.yaml
    阻止列表中的公司、人员、邮箱。替换为保留形状的令牌(
    <company-1>
    <person-1>
    <email-1>
    ),这些令牌在所有产物中保持一致,以便审核者仍能解析意图。
  3. 首次提及防护 — 遍历每个产物,查找看起来像专有名词且不在阻止列表中的大写短语。在阶段6的PR草稿展示前在线向用户展示:"Found
    Esper Labs
    (计划文档中3次,PR正文中1次)——添加到阻止列表并清理,或保留?"
目标优先级顺序:PR标题/正文草稿、每次运行的计划文档、延迟需求列表、
$CLI_DIR
中新添加的任何测试 fixture 或示例输出。对于每个目标,在清理前复制到
<path>.pre-pii-scrub
,以便用户可以审核修改内容。
纵深防御:遍历
$CLI_DIR
中的每个
*.go
文件,查找阻止列表匹配项。如果找到任何匹配项,视为阻塞——暂停并要求用户解决后再进入阶段6。代理不应在Go源码中引入PII;此检查用于捕获代理错误。
阻止列表创建:如果
~/.printing-press/amend-config.yaml
不存在,技能会创建一个包含初始列表和格式说明注释的默认文件。文件模式验证(对全局可写发出警告,对非用户所有的文件中止)。
清理报告写入
$PRESS_MANUSCRIPTS/<slug>/<run-id>/scrub-report.json
(不提交;供用户审核)。阶段结束时的用户-facing摘要:"X个令牌在Y个产物中被替换。"

Phase 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
gh
command fires.
这是第二个也是最后一个用户检查点。后续所有操作均为无人值守(推送 + 打开PR + 添加标签 + RESULT块)。在任何
gh
命令执行前,向用户展示所有即将发布的内容。

Assemble the draft

组装草稿

Compose the PR title, body, labels, and diff summary in memory. Title format follows the public library convention:
  • fix(<api-slug>): <one-line summary>
    when the scope is bugs-only
  • feat(<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)
The
<one-line summary>
is composed from the most important 1-3 findings (e.g.
surface refresh-token expiry; add drafts new + --type sent
).
PR body sections (per origin R27):
  1. Summary — 1-3 sentences naming the user pain and the shape of the fix
  2. Findings — table with ID, category, type (bug/feature), rationale
  3. Changes — output of
    git diff --stat upstream/main..HEAD
  4. Verification — build/test/dogfood/validate status from Phase 4
  5. Evidence — full GitHub URLs to the per-run plan doc and
    .printing-press-patches.json
    at the PR's HEAD SHA (captured AFTER push so links don't 404)
  6. Closes #N footer when an issue match was found in Step 6 of
    library-pr-plumbing.md
Labels:
comp:<api-slug>
always;
priority:P1
for bugs-only scope,
priority:P2
for bugs+features,
priority:P3
for all-tiers.
在内存中组合PR标题、正文、标签和差异摘要。标题格式遵循公共库约定:
  • 当范围仅为bugs时:
    fix(<api-slug>): <一行摘要>
  • 当范围包含features时:
    feat(<api-slug>): <一行摘要>
  • 混合范围时:
    feat(<api-slug>): <一行摘要>
    (feature优先,因为它是更大的契约变更)
<一行摘要>
由最重要的1-3个需求组成(例如
surface refresh-token expiry; add drafts new + --type sent
)。
PR正文章节(遵循origin R27):
  1. 摘要 — 1-3句话,说明用户痛点和修复形式
  2. 需求 — 表格,包含ID、类别、类型(bug/feature)、理由
  3. 变更
    git diff --stat upstream/main..HEAD
    的输出
  4. 验证 — 阶段4的构建/测试/dogfood/验证状态
  5. 证据 — PR的HEAD SHA对应的每次运行计划文档和
    .printing-press-patches.json
    的完整GitHub URL(推送后捕获,避免链接404)
  6. Closes #N页脚,当在
    library-pr-plumbing.md
    步骤6中找到匹配的issue时
标签:始终添加
comp:<api-slug>
;仅bugs范围添加
priority:P1
,bugs+features范围添加
priority:P2
,所有层级范围添加
priority:P3

Display before gh fires

在gh命令执行前展示

Show the user the title, body, label list, and
git diff --stat
. If Phase 5 surfaced unrecognized capitalized phrases that the user accepted as legitimate, RE-DISPLAY those inline now with the sentence each appears in:
"Reminder: PR body references
<phrase>
(you accepted as legitimate during Phase 5). Confirm before opening."
向用户展示标题、正文、标签列表和
git diff --stat
。如果阶段5发现未识别的大写短语且用户确认保留合法,现在重新内联展示这些短语及其出现的句子:
"提醒:PR正文引用了
<phrase>
(你在阶段5确认保留合法)。打开前请确认。"

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 kept
For 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
$PRESS_MANUSCRIPTS/<slug>/<run-id>/proofs/<timestamp>-amend-<cli-name>-HELD.md
and
${path%.md}.diff
. Emit a RESULT block with
status: held
and the resume path. A future
/printing-press-amend
run can detect held files and offer to resume.
For abort: emit a brief confirmation. Plan doc from U5 stays (with
status: aborted
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.
PR草稿已准备好。下一步?
  1. 按草稿打开PR(推荐)
  2. 编辑后打开——进入标题/正文的交互式审核
  3. 保存——保存计划 + 差异供以后恢复;不推送任何内容
  4. 中止——丢弃所有内容,不保留记录
对于编辑后打开:将标题和正文作为单独的可编辑块展示,接受用户的修订,重新展示完整草稿,确认后继续。
对于保存:将计划 + 差异保存到
$PRESS_MANUSCRIPTS/<slug>/<run-id>/proofs/<timestamp>-amend-<cli-name>-HELD.md
${path%.md}.diff
。输出RESULT块,包含
status: held
和恢复路径。未来的
/printing-press-amend
运行可以检测到保存的文件并提供恢复选项。
对于中止:输出简短确认。U5的计划文档会保留(前置元数据中写入
status: aborted
),以便用户有记录,但不保留其他内容。托管克隆会在下次运行时重置。

Phase 7 — PR Open (Autonomous)

阶段7 — 打开PR(自主运行)

If the user picked open or edit-then-open, run
references/library-pr-plumbing.md
Steps 5-7:
  1. Step 5
    git add "$CLI_DIR"
    + commit with conventional message + the findings list
  2. Step 6 — search for an existing issue matching the findings; link or open new; self-assign best-effort
  3. Step 7 — push the branch (push-vs-fork access mode determined in Step 1),
    gh pr create
    with
    --body-file
    , capture HEAD_SHA, apply labels
The fork/access detection, branch collision handling, and managed-clone refresh patterns are documented in detail in
references/library-pr-plumbing.md
. Do NOT inline those patterns here — the reference is the authoritative source.
After 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>/comments
P0/P1 findings are worth addressing before requesting human review."
如果用户选择打开或编辑后打开,运行
references/library-pr-plumbing.md
步骤5-7:
  1. 步骤5
    git add "$CLI_DIR"
    + 符合约定的提交消息 + 需求列表
  2. 步骤6 — 搜索与需求匹配的现有issue;链接或打开新issue;尽最大努力自分配
  3. 步骤7 — 推送分支(推送/分叉访问模式在步骤1中确定),
    gh pr create
    使用
    --body-file
    ,捕获HEAD_SHA,应用标签
分叉/访问检测、分支冲突处理和托管克隆刷新模式在
references/library-pr-plumbing.md
中有详细记录。不要在此处内联这些模式——参考文档是权威来源。
PR打开后,在用户-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
---PATCH-RESULT---
block on completion. Format:
---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
internal/cli/verify_internal_skill.go
and the matching test file. The setup-contract parity check runs as a Go test in
internal/pipeline/contracts_test.go
TestSkillSetupBlocksMatchWorkspaceContract
.)
本SKILL.md的静态 lint 检查通过以下命令运行:
bash
<PRINTING_PRESS_BIN> verify-internal-skill --dir skills/printing-press-amend
(见
internal/cli/verify_internal_skill.go
和对应的测试文件。配置合约一致性检查作为Go测试在
internal/pipeline/contracts_test.go
中运行——
TestSkillSetupBlocksMatchWorkspaceContract
。)