关于 printing-press-reprint
此技能使用当前 Printing Press 重新生成现有 CLI,并核对先前研究和已记录补丁,避免不加说明地沿用旧功能。它检查本地与公共版本,建议复用或重做研究,并将相关证据和用户选择传递给生成流程。
主要功能
- 01解析 CLI 并核对本地与公共副本
- 02检查先前研究和已记录补丁
- 03建议复用或重做研究
- 04依据评分卡提供增强选项
- 05向 Printing Press 传递上下文
适用场景
- 01Printing Press 升级后重新生成 CLI
- 02重新打印以解决已知的系统性缺陷
- 03根据当前用户画像重新评估旧功能
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mvanhorn/ cli-printing-press --skill printing-press-reprint安装后在 Claude Code 中输入/printing-press-reprint确认已加载。
详细介绍
/printing-press-reprint
在当前机器上重新生成已有的已发布 CLI。用户提供 CLI 名称,并可选择说明重新发布的原因。此技能会确保先前的 CLI 已存在于本地,建议是否复用或重做先前的研究,并将所需上下文传递给 /printing-press,供 novel-features 子代理将先前的功能与当前机器进行对照:保留、重新定位或舍弃,并说明原因,绝不默默处理。
/printing-press-reprint notion
/printing-press-reprint cal.com the new MCP intent surface landed and the prior CLI ships endpoint-mirror only
/printing-press-reprint allrecipes
运行时机
- Printing Press 有重大升级(新增 MCP 接口、新的身份验证模式、新的传输方式、评分标准变更),能让此 CLI 获益,效果胜过手动润色。
- 已发布的 CLI 存在已知的系统性缺陷,重新发布可以修复。
- 用户希望根据当前机器和当前角色重新评估先前的创新功能,而不是原样照搬。
对于一次性的代码质量修复,优先使用 /printing-press-polish——它不会重做研究或重建手稿。
设置
PRESS_HOME="${PRINTING_PRESS_HOME:-$HOME/printing-press}"
PRESS_LIBRARY="$PRESS_HOME/library"
PRESS_MANUSCRIPTS="$PRESS_HOME/manuscripts"
# Mid-pipeline callers may pass printing_press_bin: <abs-path> in the args
# bundle. Prefer it so reprint keeps using the parent skill's preflight-selected
# binary instead of re-resolving through PATH.
PRINTING_PRESS_BIN="${PRINTING_PRESS_BIN:-}"
if [ -z "$PRINTING_PRESS_BIN" ] && [ -n "${ARGUMENTS:-}" ]; then
PRINTING_PRESS_BIN="$(printf '%s\n' "$ARGUMENTS" | sed -nE 's/^[[:space:]]*printing_press_bin:[[:space:]]*(.+)$/\1/p' | head -1)"
fi
if [ -z "$PRINTING_PRESS_BIN" ]; then
PRINTING_PRESS_BIN="$(command -v cli-printing-press 2>/dev/null || true)"
fi
if [ -z "$PRINTING_PRESS_BIN" ]; then
echo "cli-printing-press binary not found."
echo "Install with: go install github.com/mvanhorn/cli-printing-press/v4/cmd/cli-printing-press@latest"
return 1 2>/dev/null || exit 1
fi
echo "PRINTING_PRESS_BIN=$PRINTING_PRESS_BIN"
阶段 A — 确认并核对是否存在
按照 /printing-press-import 的相同方式解析用户提供的参数:获取一次公开库的 registry.json,然后依次进行精确、规范化和模糊匹配。参数可以是 API slug(notion)、品牌名称(cal.com)、旧版 <api>-pp-cli 形式,或近似名称。
从匹配的注册表条目中提取:API_SLUG(取自 .name)和 LIB_PATH(取自 .path,例如 library/productivity/cal-com)。阶段 B 会使用 $LIB_PATH 获取公开补丁。对于“已发布过 | 未发布过”这一行,$LIB_PATH 保持为空——阶段 B 的获取操作会因此直接跳过。
接着检查本地已有内容,并通过读取两个来源清单中的 run_id 和 generated_at,与公开库进行核对:
| 本地 | 公开注册表 | 操作 |
|---|---|---|
| 不存在 | 不存在 | 停止——没有可重新发布的内容;建议使用 /printing-press <api> 进行首次发布 |
| 不存在 | 存在 | 调用 /printing-press-import <api>,然后继续 |
| 存在 | 不存在 | 继续——这是从未公开发布的本地 CLI;跳过导入 |
存在,run_id 相同 | 存在 | 继续,不导入 |
存在,公开版本的 generated_at 更新 | 存在 | 通过 AskUserQuestion 提供导入选项;由用户决定 |
存在,本地版本的 generated_at 更新 | 存在 | 停止——本地有尚未发布的工作;告知用户先发布或舍弃 |
调用 /printing-press-import 时,让它负责备份、覆盖、构建验证和模块路径重写。等待它顺利完成后再继续。
阶段 B — 验证可供核对的先前上下文
找到写作流水线需要知晓的两个产物:研究(用于 novel-features 第 2(d) 轮)和补丁(发布后通过 /printing-press-amend 记录的手动修复,例如规范文档未说明、但在实际使用中发现的 API 特殊行为)。
LIB_TARGET="$PRESS_LIBRARY/$API_SLUG"
LIB_RESEARCH="$LIB_TARGET/research.json"
MAN_RESEARCH=$(ls -1t "$PRESS_MANUSCRIPTS/$API_SLUG"/*/research.json 2>/dev/null | head -1)
研究缺失
如果两个研究路径都不存在,说明该已发布 CLI 早于 research.json 来源信息的引入。子代理会将此次运行视作首次发布,因此不会触发第 2(d) 轮的重新发布核对——没有可供读取的内容。说明这一情况并询问:
已发布的
<api>构建于research.json来源信息引入之前。 没有这项信息,novel-features 子代理会将此次运行视作首次 发布——没有可供核对的内容。是否要继续进行降级重新发布(实质上是首次发布,但保留二进制文件名称)?
如果用户拒绝,则退出。如果用户选择继续,记录缺少研究信息,以便交接提示注明这是一次降级重新发布。
补丁发现
可连接时,从公共来源刷新本地补丁索引,然后从本地读取,
以确保下游引用持久可靠。针对公共副本的修订可能已经合入,但未触发重新生成,因此即使 run_id 匹配,本地副本也可能滞后;此步骤可弥补这一差距。
索引有两种形式:按补丁划分的目录
.printing-press-patches/(当前形式),或旧版单数组
.printing-press-patches.json(尚未规范化的旧版 CLI)。只要可以连接,就始终检查这两种形式。
如果目录中包含补丁文件,优先使用目录;但在读取目录备用来源之前,绝不能让缺失的旧版单文件索引将 PATCH_COUNT 设为 0。
PATCHES_DIR="$LIB_TARGET/.printing-press-patches"
PATCHES_LEGACY="$LIB_TARGET/.printing-press-patches.json"
if [[ -n "$LIB_PATH" ]]; then
# Fetch the legacy shape if present, but do not treat a 404 as proof that no
# patches exist. Current library entries may carry only the per-patch
# directory below.
tmp=$(mktemp)
if gh api -H "Accept: application/vnd.github.v3.raw" \
"repos/mvanhorn/printing-press-library/contents/$LIB_PATH/.printing-press-patches.json" \
> "$tmp" 2>/dev/null; then
mv "$tmp" "$PATCHES_LEGACY"
else
rm -f "$tmp"
fi
# Fetch the current directory shape independently. This is the required
# fallback when `.printing-press-patches.json` is absent.
listing=$(gh api "repos/mvanhorn/printing-press-library/contents/$LIB_PATH/.printing-press-patches" 2>/dev/null || true)
if jq -e 'type == "array"' <<<"$listing" >/dev/null 2>&1; then
mkdir -p "$PATCHES_DIR"
jq -r '.[] | select(.name | endswith(".json")) | "\(.name)\t\(.download_url)"' <<<"$listing" \
| while IFS=$'\t' read -r name url; do
tmp=$(mktemp)
if curl -fsSL "$url" -o "$tmp" 2>/dev/null; then
mv "$tmp" "$PATCHES_DIR/$name" # atomic: a dropped transfer never leaves corrupt JSON
else
rm -f "$tmp"
fi
done
fi
fi
# Count from the first non-empty shape locally; PATCHES_SOURCE is what Phase D reads.
if [[ -d "$PATCHES_DIR" ]]; then
DIR_PATCH_COUNT=$(find "$PATCHES_DIR" -maxdepth 1 -name '*.json' ! -name '_meta.json' | wc -l | tr -d ' ')
else
DIR_PATCH_COUNT=0
fi
if [[ "$DIR_PATCH_COUNT" != "0" ]]; then
PATCH_COUNT="$DIR_PATCH_COUNT"
PATCHES_SOURCE="$PATCHES_DIR"
elif [[ -f "$PATCHES_LEGACY" ]]; then
PATCH_COUNT=$(jq '(.patches // []) | length' "$PATCHES_LEGACY" 2>/dev/null || echo 0)
PATCHES_SOURCE="$PATCHES_LEGACY"
else
PATCH_COUNT=0
PATCHES_SOURCE="$PATCHES_DIR"
fi
如果 $PATCH_COUNT == 0,或不存在索引(早于补丁约定的旧版 CLI),则跳过本小节余下内容——交接内容中不包含补丁区块。
如果 $PATCH_COUNT > 0,请在继续之前向用户简要说明:
公共
<api>中记录了$PATCH_COUNT个针对上一个已打印 CLI 的补丁。请将它们作为关注清单纳入简报。现在,重新生成和发布验证会读取这些记录;如果记录的文件或声明的调用点/pp:patch标记已不存在,就会失败关闭——不要认为索引就能证明这些自定义内容仍已发布。
将 $PATCHES_SOURCE 和 $PATCH_COUNT 保留至阶段 D。
阶段 C — 时效性建议
从最近一份先前的 research.json 中获取
researched_at,并从 .printing-press.json 中获取
printing_press_version + generated_at:
RESEARCHED_AT=$(jq -r '.researched_at // empty' "$MAN_RESEARCH" 2>/dev/null)
PRESS_VERSION=$(jq -r '.printing_press_version // empty' "$LIB_TARGET/.printing-press.json" 2>/dev/null)
GENERATED_AT=$(jq -r '.generated_at // empty' "$LIB_TARGET/.printing-press.json" 2>/dev/null)
使用 python3 计算研究内容的日历时长,以确保在 macOS/Linux 上均可移植,并能处理 generated_at 所带的微秒精度(BSD date -f 不接受小数秒;所有受支持的平台上都有 python3):
AGE_DAYS=$(python3 -c "
from datetime import datetime, timezone
ts = '$RESEARCHED_AT'.replace('Z', '+00:00')
print(int((datetime.now(timezone.utc) - datetime.fromisoformat(ts)).total_seconds() // 86400))
" 2>/dev/null)
向用户展示这两项信息——研究时长和先前的机器版本。时长阈值仅供参考,并非硬性门槛:
- 少于 30 天 → 看来可以安全复用
- 30–120 天 → 复用或许可行;用户应在重新打印原因中提及已知的 API 变更,以便子 Agent 在第 2 轮中纳入考虑
- 超过 120 天 → 建议重新研究
不要仅凭时长预测 API 变更——只描述相关信息,并允许用户自行决定。/printing-press 中阶段 0 的二进制版本升级重新验证会独立处理机器端差异;不要在此重复处理。
通过 AskUserQuestion 询问:
- 复用先前研究 — 保留先前的简报;子 Agent 会根据当前用户画像重新评估先前的新颖功能
- 重新研究 — 从头重新运行
/printing-press的阶段 1;子 Agent 仍会在第 2 轮的 (d) 项中纳入先前的新颖功能 - 先给我看看 — 显示先前简报的标题和新颖功能列表,然后在选项 1 和 2 之间再次询问
阶段 D — 移交至 /printing-press
调用 /printing-press 之前,使用先前 CLI 的评分卡和清单,判断重新打印是否应提供首次打印时无法使用的规格增强。重新打印的证据优于全新打印:它们知道哪些结构维度得分较低、哪个版本的 Printing Press 生成了先前的 CLI,以及用户说明的重新生成原因。
查找上一次手稿运行中最近的评分卡 JSON。如果不存在评分卡产物,则针对本地库副本运行新的结构评分卡:
SCORECARD_SOURCE=$(ls -1t "$PRESS_MANUSCRIPTS/$API_SLUG"/*/proofs/scorecard.json 2>/dev/null | head -1)
SCORECARD_JSON=""
if [[ -n "$SCORECARD_SOURCE" ]]; then
SCORECARD_JSON=$(cat "$SCORECARD_SOURCE" 2>/dev/null || true)
elif [[ -d "$LIB_TARGET" ]]; then
SCORECARD_SOURCE=$(mktemp)
if "$PRINTING_PRESS_BIN" scorecard --dir "$LIB_TARGET" --json > "$SCORECARD_SOURCE" 2>/dev/null; then
SCORECARD_JSON=$(cat "$SCORECARD_SOURCE" 2>/dev/null || true)
fi
rm -f "$SCORECARD_SOURCE"
SCORECARD_SOURCE=""
fi
如果 SCORECARD_JSON 为空,则继续且不提示增强,并说明此次重新打印将在没有先前评分证据的情况下进行。不要仅根据重新打印原因编造提示。
如果 SCORECARD_JSON 可用,则仅检查与生成前规格编辑相关的维度,并跳过得分已达 10/10 的维度:
- 低于 10 的
mcp_remote_transport、mcp_token_efficiency、mcp_tool_design和mcp_surface_strategy可通过/printing-pressPhase 2 章节 生成前 MCP 增强 提升。示例:- 远程传输低于 10:在重新生成前,提供
mcp.transport: [stdio, http]或 OpenAPIx-mcp.transport等效项。 - 令牌效率、工具设计或界面策略低于 10:提供
/printing-pressPhase 2 MCP 界面决策,包括针对清晰多步骤 工作流的意图,或针对大型界面的 Cloudflare 模式。
- 远程传输低于 10:在重新生成前,提供
auth_protocol低于 10,或此前的清单证据表明 CLI 使用了由 slug 推导的环境变量, 而生态系统已有规范环境变量时,可通过生成前认证增强提升。可建议将规范的auth.env_vars或 OpenAPIx-auth-env-vars指引纳入规范。- 只有当此前的 CLI 或研究表明存在符合同步条件的资源时,
data_pipeline_integrity低于 10 才是增强机会。在这种情况下,应将交接内容指向 相关的/printing-pressPhase 2 同步/缓存增强决策,而不是仅凭分数就认定应存在本地存储。
交接前,使用 AskUserQuestion 询问每个具体机会。问题应围绕评分卡证据和指定的规范章节,
而不是围绕自由发挥式改写。示例:
此前的评分卡显示
mcp_remote_transport: 5/10。是否要在重新生成前增强 MCP 传输, 并以/printing-pressPhase 2 生成前 MCP 增强 作为依据?
选项:
- 将增强纳入交接内容 - 将选定的规范修改纳入
/printing-press提示词,以便 Phase 2 在生成前更新规范。 - 本次重新生成跳过 - 此维度的规范保持不变。
- 先显示评分证据 - 打印相关评分卡行,然后在选项 1 和 2 之间重新询问。
不要自动应用增强。如果此前的评分卡已有
mcp_remote_transport: 10/10,则不要重复询问 MCP 传输问题。
如果用户接受任何机会,就在 /printing-press 交接内容中添加
## 重新生成规范增强 章节。内容应简短:说明薄弱维度、已接受的增强,以及要执行的规范
/printing-press Phase 2 章节。不要在此重复规范中的增强文本。
调用 /printing-press <api>,并将以下内容一并放入提示词:
-
标题行:说明用户已选择重新生成,因此
/printing-pressPhase 0 的库检查应选择“生成全新的 CLI”,而不是 再次询问“全新生成还是改进现有 CLI”。 -
研究模式:采用 Phase C 中的模式(
reuse或redo)。/printing-pressPhase 0 的现有复用逻辑会使用此信息。 -
用户自由填写的重新生成原因:在
User context块中原文照录。此内容会传递到简报中的## 用户愿景,并作为 Pass 2(e) 的输入提供给新颖功能子 Agent—— 这是针对“我希望 MCP 支持更好”这类诉求调整头脑风暴方向的正确入口。 -
重新生成规范增强 — 仅当上述由评分卡驱动的提示发现了用户接受的机会时才包含。 在
## 重新生成规范增强标题下列出。 -
先前补丁 — 仅当 Phase B 发现
$PATCH_COUNT > 0时包含。 在## 先前补丁标题下列出。以以下说明句开头,原文照录:
以下内容是针对之前生成的 CLI 手动修复的。它们仅供参考——自应用补丁以来, 机器可能已在上游吸收了其中一些内容。请留意,确保新生成的代码不会悄然 退化,偏离底层 API 的真实情况或架构模式,但不要将其视为需要重新应用的清单。 然后总结
$PATCHES_SOURCE中的补丁。每项应以补丁所体现的 实质内容 开头(API 的实际规则、架构模式、跨文件约定),并从各补丁的reason和validated_outcome中提取,而不只是复述summary。补丁元数据(id、files)可作为括号中的上下文,但绝不能作为标题。根据补丁数量调整本节篇幅:
- 1–3 个补丁:每个补丁用一个简短段落——先讲实质内容,再讲具体体现方式。可参考以下格式:
Linear 的个人 API 密钥应原样放入
Authorization: lin_api_…,不得添加Bearer前缀;OAuth 令牌则使用Authorization: Bearer <token>。先前发布的 CLI 只有auth set-token(默认使用 Bearer),发布后通过补丁添加了auth set-api-key以及config.go中的原始请求头路径(linear-auth-api-key-vs-oauth-token)。 - 4–9 个补丁:每个补丁用一个简洁的句子,采用相同的实质内容优先结构。
- 10 个或更多补丁:按主题分类总结(身份验证、分页、查询编码、MCP 新增项、辅助工具、分类器、错误封装)。每个主题用两三句话,并引用 2–3 个补丁
id作为依据。不要在行文中逐一列出所有条目。
结尾应提供指引,方便下游 Agent 在处理相关领域时深入查看具体补丁:
完整补丁详情:位于
$PATCHES_SOURCE下的各个补丁文件(每个<id>.json都是一个独立完整的补丁;旧版单数组.printing-press-patches.json在patches[]中包含相同字段)。 - 1–3 个补丁:每个补丁用一个简短段落——先讲实质内容,再讲具体体现方式。可参考以下格式:
不要传递单独的“这是重新打印”标记。novel-features 子 Agent 每次打印时都会无条件运行,并通过自己的发现代码片段查找先前的研究。Phase A 中导入并填充的路径正是它会检查的路径;只要先前的 research.json 存在,Pass 2(d) 就会执行。
库保留约定由 /printing-press 的 Phase 5.6(“Promote to Library”)负责,而非此技能负责。如果现有库的清单中 novel_features > 0(或 internal/cli/、internal/syncer/ 或 internal/store/ 下存在手动编写的文件),Phase 5.6 会先试运行 "$PRINTING_PRESS_BIN" regen-merge "$LIB_TARGET" --fresh "$CLI_WORK_DIR" --json,判断新生成的目录是否重建了先前的 novel 内容。如果新目录包含所有先前的 novel 内容,Phase 5.6 就会使用交换路径,并将生成文件版本差异视为预期覆盖。否则,它会通过 regen-merge --apply 执行晋升,让仍具独特性的手动编写 novel 内容在重新打印时得以保留;遇到真正的 NOVEL-COLLISION 或缺少引用对象的情况时,则会暂停以供审核。这符合 /printing-press Phase 3 必须能通过 regen-merge 合并手动编辑一节中的优先使用 regen-merge 指引。如果将来修改该阶段的路由规则,必须在同一个 PR 中更新本段——重新打印技能是触发该流程的主要入口。
交接前,将重新生成的清单文件与已跟踪的已发布目录进行比较。如果存在 $LIB_TARGET/manifest.json 或 $LIB_TARGET/tools-manifest.json,请将每个文件与 $CLI_WORK_DIR 下新生成的对应文件进行差异比较,并在交接提示中列出非空差异。将差异视为需要协调的检查点,而不是自动批准覆盖:操作人员必须决定是保留已跟踪的手动修改、将其纳入规范或研究输入,还是有意接受重新生成的值。如果已跟踪的清单字段、工具元数据或描述将被丢弃,不得悄然继续。
归属仍归 /printing-press 管理:交接流程会为同一个 API slug 运行生成步骤;当重印者与原作者不同时,生成/推广流程必须保留现有库清单中的永久 creator,同时将重印者添加到 contributors[] 中。不要通过手动编辑 creator、contributors[]、README 署名、SKILL author: 或 NOTICE 来修复;请使用当前版本的 Printing Press 二进制文件重新运行,以便清单优先保护机制一致地重写工作树和已推广的树。
交接之后
Printing Press 流程会推动后续工作。不要总结它的工作内容——让用户看到实时阶段。
如果 /printing-press 因子 Agent 的预检 HALT 而停止(简报缺少具体的 Users/Top Workflows 内容),说明复用的旧简报不符合子 Agent 要求的新架构。建议在阶段 C 选择 Redo research 后重新运行。