printing-press-import

>

INSTALLATION
npx skills add https://github.com/mvanhorn/cli-printing-press --skill printing-press-import
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

/printing-press-import

Bring a published CLI from the public library

(mvanhorn/printing-press-library)

into the internal library at ~/printing-press/library/ so it matches

the form the generator would produce. Manuscripts ride along.

/printing-press-import notion

/printing-press-import cal.com

/printing-press-import allrecipes --from-clone ~/Code/printing-press-library

The internal library is the working copy; the public library is the

durable artifact. After import, the CLI is ready for polish, emboss, or

re-publish — the publish step will re-apply the module path rewrites.

When to run

  • The public library has a CLI you don't have locally
  • The internal copy is broken, lost, or out of sync
  • You want a clean baseline before running polish on a published CLI

If the user is asking to polish a CLI and mentions "in/from the public

library" or "from the repo", suggest running this skill first.

Setup

PRESS_HOME="$HOME/printing-press"

PRESS_LIBRARY="$PRESS_HOME/library"

PRESS_MANUSCRIPTS="$PRESS_HOME/manuscripts"

SCRIPTS_DIR="$(dirname "${BASH_SOURCE[0]:-$0}")/references"

The four reference scripts live alongside this SKILL.md under

references/:

  • import-fetch.sh <library-path> <staging> [--clone <path>]
  • import-backup.sh <api-slug> (prints zip path on stdout)
  • import-rewrite.sh <staging> <api-slug>
  • import-place.sh <staging> <api-slug>

Phase 1 — Resolve the CLI

The argument can be anything natural: an API slug (notion), a brand

name (cal.com), an old CLI name (notion-pp-cli), or close enough

(Allrecipes). Resolve via the public library's registry.json

which carries name, category, api, description, and path for

every entry, in one fetch.

REGISTRY=$(mktemp)

gh api -H "Accept: application/vnd.github.v3.raw" \

  repos/mvanhorn/printing-press-library/contents/registry.json \

  > "$REGISTRY"

Match in this order:

  • **Exact name match** — jq --arg q "$ARG" '.entries[] | select(.name == $q)' "$REGISTRY"
  • Normalized exact — strip -pp-cli suffix, lowercase, dot→hyphen, then exact match
  • **Substring on name or description** — case-insensitive contains
# 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"

If you get one match: use it. If multiple: present at most 4 to the user

via AskUserQuestion showing name + description per candidate. If

zero: tell the user the public library doesn't have that CLI.

The matched entry gives you everything you need:

  • LIB_PATH from .path (e.g., library/productivity/cal-com)
  • API_SLUG from .name
  • CATEGORY from .category

Don't slurp whole files when reasoning over candidates. The fields

above are enough; if you genuinely need more, the per-CLI manifest is

just <LIB_PATH>/manifest.json and the description there can be pulled

the same way (gh api -H "Accept: ... raw" .../manifest.json | jq -r '.description').

Phase 2 — Decide on overwrite

Check whether the internal library already has this CLI:

LIB_TARGET="$PRESS_LIBRARY/$API_SLUG"

MAN_TARGET="$PRESS_MANUSCRIPTS/$API_SLUG"

If neither exists: straightforward import — proceed to Phase 3.

If either exists: read provenance from both sides to decide whether

to overwrite. Don't read whole .printing-press.json files — pull just

the fields that matter:

# 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}'

Reason over the diff:

  • **Same run_id** — public is the same generation as internal. Likely

no-op; ask before clobbering. If the user wants to import anyway

(e.g., to recover from a broken internal copy), proceed.

  • **Public newer generated_at** — public has changes the internal

doesn't. Importing is the safe move; ask the user to confirm.

  • **Internal newer generated_at** — internal has work the public

doesn't (in-progress polish, manual fixes). Importing would clobber

that. Stop and surface this to the user — they likely want to publish

the internal changes first.

  • **Either side missing .printing-press.json** — older or hand-imported.

Ask the user.

When the user confirms overwrite, the backup step in Phase 3 captures

the current internal state.

Phase 3 — Import

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"

Phase 4 — Verify internal consistency

After the move, confirm the imported CLI builds and is structurally

intact. Treat any failure as a real problem — don't paper over it.

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

Report the import outcome:

  • Source path (from registry: <category>/<api-slug>)
  • Run ID (from .printing-press.json)
  • Manuscripts run-ids placed (count + names)
  • Backup zip path (if any)
  • Build status

Polish-side hint

If the user's request to import was triggered by a polish ask (e.g.,

they said "polish notion in the public library"), suggest:

Imported $API_SLUG. To polish: /printing-press-polish $API_SLUG

The polish skill operates on the internal library, so import-then-polish

is the right flow when starting from a published CLI.

BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card