Bring a published CLI from the public library into the internal library so it's identical to a freshly-generated copy — module path reverted, manuscripts placed alongside, ready for /printing-press-polish or /printing-press-emboss. Use when the public library has a CLI you don't have locally, or to recover from a broken/lost internal copy. Trigger phrases: "import the CLI", "bring it into my library", "fetch from public library", "I don't have it locally yet".
/printing-press-import
將公開函式庫(mvanhorn/printing-press-library)中已發布的 CLI 匯入內部函式庫 $PRESS_LIBRARY/,使其與產生器產生的形式一致。手稿也會一併帶入。
/printing-press-import notion
/printing-press-import cal.com
/printing-press-import allrecipes --from-clone ~/Code/printing-press-library
內部函式庫是工作副本;公開函式庫是持久化的成品。匯入後,CLI 即可進行 polish、emboss 或重新發布——發布步驟會重新套用模組路徑改寫。
何時執行
- 公開函式庫有你本機沒有的 CLI
- 內部副本損壞、遺失或不同步
- 你想在對已發布的 CLI 執行 polish 之前取得乾淨的基準
如果使用者要求 polish 某個 CLI 並提到「在/從公開函式庫」或「從 repo」,建議先執行此技能。
設定
PRESS_HOME="${PRINTING_PRESS_HOME:-$HOME/printing-press}"
PRESS_LIBRARY="$PRESS_HOME/library"
PRESS_MANUSCRIPTS="$PRESS_HOME/manuscripts"
SCRIPTS_DIR="$(dirname "${BASH_SOURCE[0]:-$0}")/references"
if ! command -v go >/dev/null 2>&1; then
echo ""
echo "[setup-error] 找不到 Go 工具鏈。"
echo ""
echo "此 Printing Press 流程需要執行基於 Go 的建置或驗證指令。"
echo "請從 https://go.dev/dl/ 安裝 Go 1.26.5 或更新版本,然後執行以下指令確認:"
echo " go version"
echo "再重新執行此技能。"
echo ""
return 1 2>/dev/null || exit 1
fi
_pp_check_disk_space() {
_pp_disk_warn_kb="${PRINTING_PRESS_DISK_WARN_KB:-3145728}"
_pp_disk_fail_kb="${PRINTING_PRESS_DISK_FAIL_KB:-524288}"
case "$_pp_disk_warn_kb$_pp_disk_fail_kb" in
""|*[!0-9]*) return 0 ;;
esac
_pp_disk_path="$PRESS_HOME"
while [ ! -e "$_pp_disk_path" ] && [ "$_pp_disk_path" != "/" ]; do
_pp_disk_path="$(dirname "$_pp_disk_path")"
done
_pp_disk_avail_kb="$(df -Pk "$_pp_disk_path" 2>/dev/null | awk 'NR == 2 { print $4; exit }')"
case "$_pp_disk_avail_kb" in
""|*[!0-9]*) return 0 ;;
esac
if [ "$_pp_disk_avail_kb" -lt "$_pp_disk_fail_kb" ]; then
echo ""
echo "[setup-error] Printing Press 工作區磁碟空間嚴重不足。"
echo "PRESS_DISK_PATH=$_pp_disk_path"
echo "PRESS_DISK_AVAIL_KB=$_pp_disk_avail_kb"
echo "PRESS_DISK_FAIL_KB=$_pp_disk_fail_kb"
echo "請釋放磁碟空間或將 PRINTING_PRESS_HOME 設定到空間更大的磁碟區,然後重新執行此技能。"
echo ""
return 1
fi
if [ "$_pp_disk_avail_kb" -lt "$_pp_disk_warn_kb" ]; then
echo ""
echo "[low-disk] Printing Press 工作區可用空間偏低。"
echo "PRESS_DISK_PATH=$_pp_disk_path"
echo "PRESS_DISK_AVAIL_KB=$_pp_disk_avail_kb"
echo "PRESS_DISK_WARN_KB=$_pp_disk_warn_kb"
echo "此流程可能需要數 GiB 空間來存放產生的檔案、Go 建置快取、模組下載或儲存庫複製。"
echo ""
fi
}
_pp_check_disk_space || { return 1 2>/dev/null || exit 1; }
四個參考腳本與此 SKILL.md 位於同一目錄下的 references/:
import-fetch.sh <library-path> <staging> [--clone <path>]import-backup.sh <api-slug>(在 stdout 輸出 zip 路徑)import-rewrite.sh <staging> <api-slug>import-place.sh <staging> <api-slug>
如果設定階段輸出了 [low-disk],請向使用者顯示該警告並繼續執行,除非設定階段也輸出了 [setup-error]。[low-disk] 表示此次執行可能需要數 GiB 空間來存放儲存庫複製、暫存檔案、備份、Go 建置快取或模組下載。
階段 1 — 解析 CLI
參數可以是任何自然語言:API slug(notion)、品牌名稱(cal.com)、舊 CLI 名稱(notion-pp-cli)或相近名稱(Allrecipes)。透過公開函式庫的 registry.json 解析——該檔案包含每個條目的 name、category、api、description 和 path,一次擷取即可。
REGISTRY=$(mktemp)
gh api -H "Accept: application/vnd.github.v3.raw" \
repos/mvanhorn/printing-press-library/contents/registry.json \
> "$REGISTRY"
依下列順序比對:
- 精確
name比對 —jq --arg q "$ARG" '.entries[] | select(.name == $q)' "$REGISTRY" - 正規化後精確比對 — 移除
-pp-cli後綴、轉小寫、點號轉連字號,再精確比對 name或description子字串比對 — 不區分大小寫的包含
# 精確比對:
jq --arg q "$ARG" '.entries[] | select(.name == $q)' "$REGISTRY"
# 正規化後精確比對($ARG2 為小寫、點號轉連字號、移除後綴後):
jq --arg q "$ARG2" '.entries[] | select(.name == $q)' "$REGISTRY"
# 模糊比對(name 或 description 子字串):
jq --arg q "$ARG2" '.entries[]
| select((.name | ascii_downcase | contains($q | ascii_downcase))
or (.description | ascii_downcase | contains($q | ascii_downcase)))
' "$REGISTRY"
如果只有一個比對結果:直接使用。如果有多個:透過 AskUserQuestion 向使用者顯示最多 4 個候選項目,每個顯示 name 和 description。如果沒有比對結果:告知使用者公開函式庫中沒有該 CLI。
比對到的條目會提供你所需的一切:
LIB_PATH來自.path(例如library/productivity/cal-com)API_SLUG來自.nameCATEGORY來自.category
在判斷候選項目時,不要讀取整個檔案。 上述欄位已足夠;如果你真的需要更多資訊,每個 CLI 的 manifest 位於 <LIB_PATH>/manifest.json,其中的 description 可以用相同方式取得(gh api -H "Accept: ... raw" .../manifest.json | jq -r '.description')。
階段 2 — 決定是否覆寫
檢查內部函式庫是否已有此 CLI:
LIB_TARGET="$PRESS_LIBRARY/$API_SLUG"
MAN_TARGET="$PRESS_MANUSCRIPTS/$API_SLUG"
如果兩者都不存在: 直接匯入——進入階段 3。
如果任一存在: 讀取雙方的 provenance 資訊來決定是否覆寫。不要讀取整個 .printing-press.json 檔案——只擷取相關欄位:
# 內部 provenance(如果存在):
jq '{run_id, generated_at, printing_press_version, spec_checksum}' \
"$LIB_TARGET/.printing-press.json" 2>/dev/null
# 公開 provenance(一次擷取原始內容):
gh api -H "Accept: application/vnd.github.v3.raw" \
repos/mvanhorn/printing-press-library/contents/$LIB_PATH/.printing-press.json \
| jq '{run_id, generated_at, printing_press_version, spec_checksum}'
根據差異進行判斷:
- 相同的
run_id— 公開版本與內部版本是同一世代。可能無需動作;覆寫前先詢問。如果使用者無論如何都想匯入(例如要從損壞的內部副本復原),則繼續。 - 公開版本的
generated_at較新 — 公開版本有內部版本沒有的變更。匯入是安全的做法;請使用者確認。 - 內部版本的
generated_at較新 — 內部版本有公開版本沒有的工作(進行中的 polish、手動修正)。匯入會覆寫這些內容。停止並告知使用者——他們可能想先發布內部變更。 - 任一方缺少
.printing-press.json— 較舊版本或手動匯入。詢問使用者。
當使用者確認要覆寫時,階段 3 的備份步驟會捕捉目前的內部狀態。
階段 3 — 匯入
STAGING=$(mktemp -d)
# 擷取(遠端,除非傳入了 --from-clone)
if [[ -n "${CLONE_PATH:-}" ]]; then
bash "$SCRIPTS_DIR/import-fetch.sh" "$LIB_PATH" "$STAGING" --clone "$CLONE_PATH"
else
bash "$SCRIPTS_DIR/import-fetch.sh" "$LIB_PATH" "$STAGING"
fi
# 如果有任何東西要被覆寫則進行備份。在 stdout 輸出 zip 路徑。
if [[ -d "$LIB_TARGET" || -d "$MAN_TARGET" ]]; then
BACKUP_ZIP=$(bash "$SCRIPTS_DIR/import-backup.sh" "$API_SLUG")
echo "備份至:$BACKUP_ZIP"
fi
# 還原發布步驟的模組路徑改寫。
bash "$SCRIPTS_DIR/import-rewrite.sh" "$STAGING" "$API_SLUG"
# 原子性地將暫存目錄移至目標位置。
bash "$SCRIPTS_DIR/import-place.sh" "$STAGING" "$API_SLUG"
階段 4 — 驗證內部一致性
移動完成後,確認匯入的 CLI 可以建置且結構完整。將任何失敗視為真正的問題——不要敷衍了事。
cd "$LIB_TARGET"
# 模組路徑應為本地形式
grep -q "^module ${API_SLUG}-pp-cli\$" go.mod \
|| { echo "失敗:go.mod 仍使用公開模組路徑"; exit 1; }
# 原始碼中不應遺留公開模組路徑
if grep -rq "github.com/mvanhorn/printing-press-library/library" \
--include='*.go' --include='*.yaml' --include='*.yml' .; then
echo "失敗:原始碼仍參考公開模組路徑"
exit 1
fi
# 建置
go build ./... \
|| { echo "失敗:go build"; exit 1; }
# 自我檢查(doctor)
make doctor 2>/dev/null \
|| ./bin/${API_SLUG}-pp-cli doctor 2>/dev/null \
|| true # 盡力而為;並非所有 CLI 都有相同的 doctor 機制
回報匯入結果:
- 來源路徑(來自 registry:
<category>/<api-slug>) - Run ID(來自
.printing-press.json) - 放置的手稿 run-id(數量與名稱)
- 備份 zip 路徑(如果有)
- 建置狀態
Polish 側提示
如果使用者的匯入請求是由 polish 需求觸發(例如他們說「polish 公開函式庫中的 notion」),建議:
已匯入 $API_SLUG。若要進行 polish:/printing-press-polish $API_SLUG
Polish 技能作用於內部函式庫,因此從已發布的 CLI 開始時,先匯入再 polish 是正確的流程。






