printing-press-publish

Publish a generated CLI to the printing-press-library repo

By mvanhorn · 6,086 installs

npx skills add mvanhorn/cli-printing-press --skill printing-press-publish

Source repository · Upstream listing

/printing press publish Publish a generated CLI from your local library to the [printing press library](https://github.com/mvanhorn/printing press library) repo as a pull request. PR shape guard This skill opens only a generated CLI publish PR or, with blocked api journal , a blocked apis.json journal PR. It never opens a docs only, plan, proposal, or spec PR as a substitute for a CLI that is not ready to publish. If generation, validation, or live testing is blocked, report the exact blocker and stop. Direct User Invocation Required Publishing can fork mvanhorn/printing press library , push a branch, and open or update a PR. Before setup or validation, check the invocation context. If this skill was invoked as a chained continuation from printing press polish 's Publish Offer, including an AskUserQuestion answer or auto resolved polish recommendation, stop immediately and tell the user to send /printing press publish <cli name from polish in a fresh message. A fresh user authored request that explicitly asks to publish is sufficient; do not add another confirmation prompt on top of a direct publish request. If the fresh user authored request includes from polish , record POLISH HANDOFF=true for the terminal state step and ignore that marker when resolving the CLI name. The marker is not a second confirmation and is not passed to cli printing press ; it only preserves standalone polish's old post publish retro offer after the fresh turn publish completes. If the request includes blocked api journal , enter Blocked API Journal Mode below instead of the normal printed CLI publish flow. This mode may be invoked from /printing press 's hold path menu after the user explicitly chose "Add to blocked API journal"; that parent menu choice is sufficient user authorization for the public library journal write. Do not require a second fresh turn invocation for this journal only mode. If the fresh user authored request includes skip live test=<reason , record the exact non empty reason as SKIP LIVE TEST REASON and remove the flag before resolving the CLI name. This is the only supported escape valve for the publish time live test gate. Use it only for auth unavailable, known upstream outage, LAN unreachable hardware APIs, or similarly concrete operator approved cases; never infer a skip from ordinary latency or from the presence of an older Phase 5 marker. The public library treats library/<category /<api slug /.printing press.json and manifest.json as the source of truth for registry display fields. Do not edit registry.json , README catalog cells, or cli skills/pp <api slug /SKILL.md in publish PRs; all three are bot regenerated post merge by the library's own workflows. The library's Fail on changes to generated artifacts check in verify library conventions.yml hard fails any PR — fork or same repo — whose diff against base touches registry.json or cli skills/pp /SKILL.md , so a publish that includes either is pre rejected before review. The public library also owns per CLI release accounting. Do not manually bump CHANGELOG.md , .printing press release.json , or runtime var version = ... for a publish PR. Fresh printed CLIs may include blank release ledger skeletons; the library's post merge workflow assigns the final YYYY.M.N release and stamps the runtime version after merge. When replacing an existing public library CLI, preserve its existing release ledger files so changelog history is not lost in the reprint PR. blocked apis.json is different: it is a hand maintained public library journal, not a generated registry surface. Journal only PRs may edit blocked apis.json and must not stage library/ , registry.json , README catalog cells, or cli skills/ . Blocked API Journal Mode Use this mode only when the invocation includes blocked api journal . It records a held /printing press attempt whose blocker is likely to repeat for other users until a machine or upstream issue changes. Required fields from the caller: slug : canonical API slug, not the CLI binary name. attempted at : YYYY MM DD . verdict : hold . reason : concise blocker reason, with no secrets, local paths, cookies, tokens, or account specific details. blocking issue : Printing Press issue number if known, otherwise null . permanent : boolean. If the caller did not provide one of these fields, infer only safe values from the current run context. If reason is missing or vague, stop and ask for one specific blocker sentence; do not write an unhelpful journal entry. Run the normal Setup, Configuration, scoped clone cleanup, and GitHub auth checks, then prepare the public library clone exactly as the normal publish flow does: fork if needed, ensure upstream points to mvanhorn/printing press library , fetch upstream , and reset the clone to upstream/main before editing. Then update only $PUBLISH REPO DIR/blocked apis.json : Create a journal branch and PR: Open the PR against mvanhorn/printing press library with a body that includes: the held API slug and reason whether the block is permanent or tied to blocking issue the expected Phase 0 behavior: future /printing press <api slug runs warn before repeating the attempt After the PR is open, report the URL and stop. Do not continue into normal printed CLI package, live test, registry, or skill mirror steps. Setup Before doing anything else: <! PRESS SETUP CONTRACT START <! PRESS SETUP CONTRACT END After running the setup contract, capture the PRINTING PRESS BIN=<abs path line from stdout. Every subsequent cli 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 cli printing press resolves against the user's default PATH and a stale global can shadow the local build. If setup emitted [go toolchain old] or [low disk] , surface the advisory to the user and continue unless setup also emitted [setup error] . [go toolchain old] means later Go commands may download the required toolchain or fail when downloads are blocked; [low disk] means this run may need several GiB for generated files, Go build cache, module downloads, or repository clones. 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: "cli 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/cli printing press@latest to update." Configuration Publish config $PUBLISH CONFIG stores persistent publish settings as JSON. On first publish, create it with defaults. The user can edit it to change the library repo or module path base. The module path base field sets the Go module path prefix for published CLIs. During packaging, the full module path is constructed as <module path base /<category /<api slug . If the user wants CLIs published to a different repo or path, they edit this field. Store expanded absolute paths for clone path and scope dir so cleanup can check them without relying on shell specific ~ expansion. The managed by field is required before cleanup may delete anything. Scoped clone cleanup Before creating or reusing $PUBLISH REPO DIR , prune scoped publish clones whose source worktree no longer exists. This keeps concurrent worktrees isolated without accumulating one library clone forever per short lived worktree. Step 1: Prerequisites Verify gh is authenticated: If this fails, stop and tell the user: "GitHub CLI is not authenticated. Run gh auth login first." Step 2: Resolve API Slug Run: Parse the JSON output into a list of CLIs. The library is now keyed by API slug (the directory name), not CLI name. Name resolution order (matches the score skill for consistency): 1. Exact match: If the argument matches a directory name (API slug) exactly, use it 2. CLI name match: If no exact match, try matching against cli name fields, then derive the API slug from the manifest's api name field 3. Suffix match: If no match yet, try <argument pp cli against cli name fields 4. Glob match: If no suffix match, search for entries where cli name or api name contains the argument as a substring. Cap at 5 most recent matches. If multiple matches, present them via AskUserQuestion and let the user pick 5. No match: List all available CLIs and ask the user to pick or re enter 6. No argument: If invoked with no name, list all CLIs sorted by modification time and let the user pick Once resolved, read the manifest's api name field to get the API slug. Use this slug for all downstream operations (branch names, registry entries, collision detection, path construction). The cli name from the manifest is only used for binary level operations. When presenting matches, show the API slug and modification time in a human friendly format (e.g., "2 hours ago", "3 days ago"). Step 3: Determine Category Read .printing press.json from the resolved CLI directory. Category resolution order: 1. If the manifest has a category field, present it for confirmation: "Publishing as <category . OK?" Give the user the option to change it 2. If the manifest does not provide a category, present the full list via AskUserQuestion: developer tools, monitoring, cloud, project management productivity, social and messaging, sales and crm, marketing payments, auth, commerce, ai, food and dining, health, maps, media and entertainment, devices, other travel Step 3.5: The Greptile review contract — read before opening the PR Every PR into the public library gets an automated Greptile review plus a Greptile policy gate CI job. The canonical contract is the library's [ AGENTS.md → "Automated code review with Greptile" ](https://github.com/mvanhorn/printing press library/blob/main/AGENTS.md automated code review with greptile); the essentials: The bar is resolving every Greptile finding before merge — the 0 5 score is a confidence signal, not the gate. A 4/5 with everything resolved is ready; a 5/5 with open P1s is not. Treat every P0 and P1 as blocking; P2s need a fix or a concrete deferral reply. Reviews are incremental : every push re triggers a fresh review that can surface new findings. Drive the PR to a stable green — never declare done after round one. Read the latest greptile apps top level summary, not just inline threads. Summaries can carry actionable Comments Outside Diff blocks even when the thread list is empty. Run the repo's review state helper before declaring ready: Timeout recovery : if the policy gate fails with Timed out waiting for Greptile Review to complete (large new CLI diffs are the common trigger), the gate auto posts @greptileai review after ~3 minutes; if that doesn't recover, post @greptileai review yourself and wait. The score gate : the policy gate requires the latest Greptile comment on the current head SHA to carry Confidence Score: ≥ 4/5 . A new push re runs it — keep the score meeting threshold on the final head. Step 4: Validate Run: govulncheck in this step is intentionally scoped to <cli dir only. It uses the default govulncheck ./... mode so reachable symbol findings block publish, while merely required vulnerable modules without a call path do not become release blockers. Do not replace this with a full public library scan or govulncheck show verbose . Parse the JSON result. Display each chec