printing-press-import について
Printing Press の公開ライブラリにある公開済み CLI を、原稿とともに内部の作業用ライブラリへ取り込むスキルです。レジストリで CLI 名を解決し、上書き前に由来を確認して、必要に応じてバックアップを作成し、モジュールパスを書き換えてビルドを検証します。
主な機能
- 01レジストリによる CLI 名の解決
- 02CLI と原稿のインポート
- 03上書き前の由来情報の確認
- 04既存ライブラリのバックアップ
- 05モジュールパスの書き換えとビルド検証
活用シーン
- 01公開ライブラリから内部ライブラリへの CLI 取り込み
- 02欠落または同期ずれした内部コピーの復旧
- 03公開済み CLI の修正や再公開の準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mvanhorn/ cli-printing-press --skill printing-press-importインストール後、Claude Code で/printing-press-importを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/import-backup.shimport-fetch.shimport-place.shimport-rewrite.sh詳細
/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 を実行する前に、クリーンなベースラインを用意したい場合
ユーザーが CLI の polish を依頼し、「公開ライブラリ内の/から」または「リポジトリから」と述べた場合は、最初にこのスキルを実行するよう提案してください。
セットアップ
PRESS_HOME="${PRINTING_PRESS_HOME:-$HOME/printing-press}"
PRESS_LIBRARY="$PRESS_HOME/library"
PRESS_MANUSCRIPTS="$PRESS_HOME/manuscripts"
SCRIPTS_DIR="$(dirname "${BASH_SOURCE[0]:-.}")/references"
if ! command -v go >/dev/null 2>&1; then
echo ""
echo "[setup-error] Go toolchain not found."
echo ""
echo "This Printing Press flow runs Go-based build or validation commands."
echo "Install Go 1.26.10 or newer from https://go.dev/dl/, then verify with:"
echo " go version"
echo "Then re-run this skill."
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 'BEGIN {
if ((getline header) <= 0 || (getline record) <= 0) exit
field_count = split(record, fields)
if (field_count >= 4) print fields[4]
}')"
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] Critically low disk space on the Printing Press workspace volume."
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 "Free disk space or set PRINTING_PRESS_HOME to a volume with more room, then re-run this skill."
echo ""
return 1
fi
if [ "$_pp_disk_avail_kb" -lt "$_pp_disk_warn_kb" ]; then
echo ""
echo "[low-disk] Printing Press workspace volume is low on free space."
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 "This flow may need several GiB for generated files, Go build cache, module downloads, or repository clones."
echo ""
fi
}
_pp_check_disk_space || { return 1 2>/dev/null || exit 1; }
4 つの参照スクリプトは、references/ 内のこの SKILL.md と同じ場所にあります。
import-fetch.sh <library-path> <staging> [--clone <path>]import-backup.sh <api-slug>(zip パスを標準出力に出力します)import-rewrite.sh <staging> <api-slug>import-place.sh <staging> <api-slug>
セットアップで [low-disk] が出力された場合は、その注意事項をユーザーに伝え、セットアップで [setup-error] も出力されていない限り続行してください。[low-disk] は、この実行でリポジトリのクローン、ステージングファイル、バックアップ、Go ビルドキャッシュ、またはモジュールのダウンロードに数 GiB の空き容量が必要になる可能性があることを示します。
フェーズ 1 — CLI の特定
引数には、API スラッグ(notion)、ブランド名(cal.com)、以前の CLI 名(notion-pp-cli)、または近い名称(Allrecipes)など、自然な形式を指定できます。公開ライブラリの registry.json から特定してください。このファイルには、すべてのエントリの name、category、api、description、path が 1 回の取得で含まれています。
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の部分一致 — 大文字と小文字を区別せずに検索
# Exact:
jq --arg q "$ARG" '.entries[] | select(.name == $q)' "$REGISTRY"
# Normalized exact (after $ARG2 = lowercase, dot→hyphen, suffix-stripped):
jq --arg q "$ARG2" '.entries[] | select(.name == $q)' "$REGISTRY"
# Fuzzy (substring on name or description):
jq --arg q "$ARG2" '.entries[]
| select((.name | ascii_downcase | contains($q | ascii_downcase))
or (.description | ascii_downcase | contains($q | ascii_downcase)))
' "$REGISTRY"
一致が 1 件の場合はそれを使用します。複数の場合は、候補ごとに name と description を示し、AskUserQuestion を使って最大 4 件をユーザーに提示します。一致が 0 件の場合は、公開ライブラリにその CLI がないことをユーザーに伝えます。
一致したエントリから、必要な情報をすべて取得できます。
.pathからLIB_PATH(例:library/productivity/cal-com).nameからAPI_SLUG.categoryからCATEGORY
候補を検討する際に、ファイル全体を読み込まないでください。上記のフィールドで十分です。どうしても詳細が必要な場合、CLI ごとのマニフェストは <LIB_PATH>/manifest.json にあります。そこから説明を同じ方法で取得できます(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 に進みます。
どちらかが存在する場合: 両方のプロベナンスを確認して、上書きするか判断します。.printing-press.json ファイル全体を読まず、必要なフィールドだけを取得してください。
# Internal provenance (if present):
jq '{run_id, generated_at, printing_press_version, spec_checksum}' \
"$LIB_TARGET/.printing-press.json" 2>/dev/null
# Public provenance (one-shot via raw):
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)
# Fetch (remote unless --from-clone was passed)
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
# Backup if anything is being clobbered. Prints zip path on stdout.
if [[ -d "$LIB_TARGET" || -d "$MAN_TARGET" ]]; then
BACKUP_ZIP=$(bash "$SCRIPTS_DIR/import-backup.sh" "$API_SLUG")
echo "Backed up to: $BACKUP_ZIP"
fi
# Reverse the publish-step module path rewrites.
bash "$SCRIPTS_DIR/import-rewrite.sh" "$STAGING" "$API_SLUG"
# Atomically move staging into place.
bash "$SCRIPTS_DIR/import-place.sh" "$STAGING" "$API_SLUG"
フェーズ 4 — 内部整合性を検証する
移動後、インポートされた CLI がビルドでき、構造的に 無傷であることを確認します。失敗はすべて実際の問題として扱ってください — 見て見ぬふりをしてはいけません。
cd "$LIB_TARGET"
# Module path is local form
grep -q "^module ${API_SLUG}-pp-cli\$" go.mod \
|| { echo "FAIL: go.mod still on public module path"; exit 1; }
# No public module path leaked into source
if grep -rq "github.com/mvanhorn/printing-press-library/library" \
--include='*.go' --include='*.yaml' --include='*.yml' .; then
echo "FAIL: source still references public module path"
exit 1
fi
# Build
go build ./... \
|| { echo "FAIL: go build"; exit 1; }
# Doctor (self-check)
make doctor 2>/dev/null \
|| ./bin/${API_SLUG}-pp-cli doctor 2>/dev/null \
|| true # best-effort; not all CLIs have doctor wired the same way
インポートの結果を報告します。
- ソースパス(レジストリから:
<category>/<api-slug>) - 実行 ID(
.printing-press.jsonから) - 配置されたマニュスクリプトの実行 ID(件数 + 名前)
- バックアップ zip のパス(存在する場合)
- ビルドステータス
ポリッシュ側のヒント
ユーザーのインポート要求がポリッシュの依頼によって引き起こされた場合(例: 「public library の notion をポリッシュして」と言った場合)、次を提案してください:
Imported $API_SLUG. To polish: /printing-press-polish $API_SLUG
ポリッシュスキルは内部ライブラリに対して動作するため、公開された CLI から始める場合は インポートしてからポリッシュするのが適切なフローです。