# {{.ProseName}} CLI
{{- $canonicalEnvVar := .Auth.CanonicalEnvVar}}
{{- if and .Narrative .Narrative.Headline}}

**{{.Narrative.Headline}}**
{{- else}}

{{.Description}}
{{- end}}
{{- if and .Narrative .Narrative.ValueProp}}

{{.Narrative.ValueProp}}
{{- end}}
{{- if .WebsiteURL}}

Learn more at [{{.ProseName}}]({{.WebsiteURL}}).
{{- end}}
{{- if .Printer}}

Printed by [@{{.Printer}}](https://github.com/{{.Printer}}){{if .PrinterName}} ({{.PrinterName}}){{end}}.
{{- end}}

## Install

The recommended path installs both the `{{.Name}}-pp-cli` binary and the `pp-{{.Name}}` agent skill (Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, and other agents supported by the upstream [`skills`](https://github.com/vercel-labs/skills) CLI) in one shot:

```bash
npx -y @mvanhorn/printing-press install {{.Name}}
```

For CLI only (no skill):

```bash
npx -y @mvanhorn/printing-press install {{.Name}} --cli-only
```

For skill only — installs the skill into the same agents as the default command above, but skips the CLI binary (use this to update or reinstall just the skill):

```bash
npx -y @mvanhorn/printing-press install {{.Name}} --skill-only
```

To constrain the skill install to one or more specific agents (repeatable — agent names match the [`skills`](https://github.com/vercel-labs/skills) CLI):

```bash
npx -y @mvanhorn/printing-press install {{.Name}} --agent claude-code
npx -y @mvanhorn/printing-press install {{.Name}} --agent claude-code --agent codex
```
{{ if .Category}}
### Without Node (Go fallback)

If `npx` isn't available (no Node, offline), install the CLI directly via Go (requires Go 1.26.3 or newer):

```bash
go install github.com/mvanhorn/printing-press-library/library/{{.Category}}/{{.Name}}/cmd/{{.Name}}-pp-cli@latest
```

This installs the CLI only — no skill.
{{- else}}
### Without Node

The generated install path is category-agnostic until this CLI is published. If `npx` is not available before publish, install Node or use the category-specific Go fallback from the public-library entry after publish.
{{- end}}

### Pre-built binary

Download a pre-built binary for your platform from the [latest release](https://github.com/mvanhorn/printing-press-library/releases/tag/{{.Name}}-current). On macOS, clear the Gatekeeper quarantine: `xattr -d com.apple.quarantine <binary>`. On Unix, mark it executable: `chmod +x <binary>`.

<!-- pp-hermes-install-anchor -->
## Install for Hermes

From the Hermes CLI:

```bash
hermes skills install mvanhorn/printing-press-library/cli-skills/pp-{{.Name}} --force
```

Inside a Hermes chat session:

```bash
/skills install mvanhorn/printing-press-library/cli-skills/pp-{{.Name}} --force
```

## Install for OpenClaw

Tell your OpenClaw agent (copy this):

```
Install the pp-{{.Name}} skill from https://github.com/mvanhorn/printing-press-library/tree/main/cli-skills/pp-{{.Name}}. The skill defines how its required CLI can be installed.
```

## Use with Claude Desktop

This CLI ships an [MCPB](https://github.com/modelcontextprotocol/mcpb) bundle — Claude Desktop's standard format for one-click MCP extension installs (no JSON config required).
{{- if or (eq .Auth.Type "cookie") (eq .Auth.Type "composed")}}

The bundle reuses your local browser session — set it up first if you haven't:

```bash
{{.Name}}-pp-cli auth login --chrome
```
{{- else if eq .Auth.Type "oauth2"}}

The bundle reuses your local OAuth tokens — authenticate first if you haven't:

```bash
{{.Name}}-pp-cli auth login
```
{{- else if and (eq .Auth.Type "bearer_token") (not $canonicalEnvVar)}}

Store your token first if you haven't:

```bash
{{.Name}}-pp-cli auth set-token YOUR_TOKEN_HERE
```
{{- end}}

To install:

1. Download the `.mcpb` for your platform from the [latest release](https://github.com/mvanhorn/printing-press-library/releases/tag/{{.Name}}-current).
2. Double-click the `.mcpb` file. Claude Desktop opens and walks you through the install.
{{- if and $canonicalEnvVar (ne .Auth.Type "none") (ne .Auth.Type "cookie") (ne .Auth.Type "composed")}}
3. Fill in `{{$canonicalEnvVar.Name}}` when Claude Desktop prompts you.
{{- end}}

Requires Claude Desktop 1.0.0 or later. Pre-built bundles ship for macOS Apple Silicon (`darwin-arm64`) and Windows (`amd64`, `arm64`); for other platforms, use the manual config below.

<details>
<summary>Manual JSON config (advanced)</summary>

If you can't use the MCPB bundle (older Claude Desktop, unsupported platform), install the MCP binary and configure it manually.

{{ if .Category}}
```bash
go install github.com/mvanhorn/printing-press-library/library/{{.Category}}/{{.Name}}/cmd/{{.Name}}-pp-mcp@latest
```
{{- else}}
Install the MCP binary from this CLI's published public-library entry or pre-built release.
{{- end}}

Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "{{.Name}}": {
      "command": "{{.Name}}-pp-mcp"{{- if and $canonicalEnvVar (ne .Auth.Type "none") (ne .Auth.Type "cookie") (ne .Auth.Type "composed")}},
      "env": {
{{- range .EndpointTemplateVars}}
        "{{envName $.Name}}_{{upper .}}": "{{if eq . "shop"}}<your-store>.myshopify.com{{else if eq . "api_version"}}{{$.Version}}{{else}}<{{.}}>{{end}}",
{{- end}}
        "{{$canonicalEnvVar.Name}}": "<your-key>"
      }{{- end}}
    }
  }
}
```

</details>
{{- if and .Narrative .Narrative.AuthNarrative}}

{{if .Auth.Optional}}## Optional: API Key{{else}}## Authentication{{end}}

{{if .Auth.Optional}}**All core commands work without setup.** The API key below is only needed to unlock additional features.

{{end}}{{.Narrative.AuthNarrative}}
{{- end}}

## Quick Start
{{- if and .Narrative .Narrative.QuickStart}}

```bash
{{- range .Narrative.QuickStart}}
{{if .Comment}}# {{.Comment}}
{{end}}{{.Command}}

{{end -}}
```
{{- else}}

### 1. Install

See [Install](#install) above.
{{- if eq .Auth.Type "api_key"}}

### 2. Set Up Credentials

{{- if .GraphQLEndpointPath}}
This CLI talks to the {{.ProseName}} GraphQL API at `{{.BaseURL}}{{.GraphQLEndpointPath}}`.
{{- end}}
{{- if .EndpointTemplateVars}}

Set the endpoint variables for the tenant, workspace, or API version you want this CLI to use:

```bash
{{- range .EndpointTemplateVars}}
export {{endpointTemplateEnvName .}}="{{if eq . "shop"}}<your-store>.myshopify.com{{else if eq . "api_version"}}{{$.Version}}{{else}}<{{.}}>{{end}}"
{{- end}}
```
{{- end}}

Get your API key from your API provider's developer portal. The key typically looks like a long alphanumeric string.
{{- with $canonicalEnvVar}}

```bash
export {{.Name}}="<paste-your-key>"
```

You can also persist this in your config file at `{{$.Config.Path}}`.
{{- end}}
{{- else if eq .Auth.Type "oauth2"}}

### 2. Authenticate

Authorize via your browser:

```bash
{{.Name}}-pp-cli auth login
```

This opens a browser window to complete the OAuth2 flow. Your tokens are stored locally and refreshed automatically.
{{- else if eq .Auth.Type "bearer_token"}}

### 2. Set Up Credentials

Get your access token from your API provider's developer portal, then store it:

```bash
{{.Name}}-pp-cli auth set-token YOUR_TOKEN_HERE
```
{{- if .BearerRefresh.Enabled}}

If commands start returning auth errors after working for a while, refresh the public client bearer token from the live web bundle:

```bash
{{.Name}}-pp-cli doctor --refresh-bearer
{{.Name}}-pp-cli refresh-bearer
```
{{- end}}
{{- with $canonicalEnvVar}}

Or set it via environment variable:

```bash
export {{.Name}}="your-token-here"
```
{{- end}}
{{- else if or (eq .Auth.Type "cookie") (eq .Auth.Type "composed")}}

### 2. Authenticate

This CLI uses your browser session for authentication. Log in to {{.Auth.CookieDomain}} in Chrome, then:

```bash
{{.Name}}-pp-cli auth login --chrome
```

Requires a cookie extraction tool. Install one:

```bash
pip install pycookiecheat          # Python (recommended)
brew install barnardb/cookies/cookies  # Homebrew
```

When your session expires, run `auth login --chrome` again.
{{- end}}

### {{if and (ne .Auth.Type "") (ne .Auth.Type "none")}}3{{else}}2{{end}}. Verify Setup

```bash
{{.Name}}-pp-cli doctor
```

This checks your configuration{{if and (ne .Auth.Type "") (ne .Auth.Type "none")}} and credentials{{end}}.

{{- $firstCmd := firstCommandExample .Resources}}
{{- if $firstCmd}}

### {{if and (ne .Auth.Type "") (ne .Auth.Type "none")}}4{{else}}3{{end}}. Try Your First Command

```bash
{{.Name}}-pp-cli {{$firstCmd}}
```
{{- end}}
{{- end}}
{{- if .NovelFeatures}}

## Unique Features

These capabilities aren't available in any other tool for this API.
{{- $groups := groupNovelFeatures .NovelFeatures}}
{{- if $groups}}
{{- range $groups}}

### {{.Name}}
{{range .Features}}
- **`{{.Command}}`** — {{.Description}}
{{- if .WhyItMatters}}

  _{{.WhyItMatters}}_
{{- end}}
{{- if .Example}}

  ```bash
  {{.Example}}
  ```
{{- end}}
{{- end}}
{{- end}}
{{- else}}
{{range .NovelFeatures}}
- **`{{.Command}}`** — {{.Description}}
{{- if .WhyItMatters}}

  _{{.WhyItMatters}}_
{{- end}}
{{- if .Example}}

  ```bash
  {{.Example}}
  ```
{{- end}}
{{- end}}
{{- end}}
{{- end}}

## Usage

Run `{{.Name}}-pp-cli --help` for the full command reference and flag list.

## Commands
{{range $name, $resource := .Resources}}
### {{$name}}

{{$resource.Description}}
{{range $eName, $endpoint := $resource.Endpoints}}
{{- if index $.PromotedResourceNames $name}}
- **`{{$.Name}}-pp-cli {{$name}}{{positionalArgs $endpoint}}`** - {{$endpoint.Description}}
{{- else}}
- **`{{$.Name}}-pp-cli {{$name}} {{kebab $eName}}`** - {{$endpoint.Description}}
{{- end}}
{{- end}}
{{end}}

## Output Formats
{{- $example := firstCommandExample .Resources}}
{{- if $example}}

```bash
# Human-readable table (default in terminal, JSON when piped)
{{.Name}}-pp-cli {{$example}}

# JSON for scripting and agents
{{.Name}}-pp-cli {{$example}} --json

# Filter to specific fields
{{.Name}}-pp-cli {{$example}} --json --select id,name,status

# Dry run — show the request without sending
{{.Name}}-pp-cli {{$example}} --dry-run

# Agent mode — JSON + compact + no prompts in one flag
{{.Name}}-pp-cli {{$example}} --agent
```
{{- else}}

Every command supports these output flags:

- `--json` — structured output for scripting and agents
- `--select id,name,status` — filter to specific fields
- `--dry-run` — preview the request without sending
- `--agent` — JSON + compact + non-interactive in one flag
{{- end}}

## Agent Usage

This CLI is designed for AI agent consumption:

- **Non-interactive** - never prompts, every input is a flag
- **Pipeable** - `--json` output to stdout, errors to stderr
- **Filterable** - `--select id,name` returns only fields you need
- **Previewable** - `--dry-run` shows the request without sending
{{- if .HasWriteCommands}}
- **Explicit retries** - add `--idempotent` to create retries{{if .HasDelete}} and `--ignore-missing` to delete retries{{end}} when a no-op success is acceptable
- **Confirmable** - `--yes` for explicit confirmation of destructive actions
- **Piped input** - write commands can accept structured input when their help lists `--stdin`
{{- else}}
- **Read-only by default** - this CLI does not create, update, delete, publish, send, or mutate remote resources
{{- end}}
{{- if .HasDataLayer}}
- **Offline-friendly** - sync/search commands can use the local SQLite store when available
{{- end}}
- **Agent-safe by default** - no colors or formatting unless `--human-friendly` is set

Exit codes: `0` success, `2` usage error, `3` not found{{if .HasAuth}}, `4` auth error{{end}}, `5` API error, `7` rate limited, `10` config error.
{{- if and .HasDataLayer .Cache.Enabled}}

## Freshness

This CLI owns bounded freshness for registered store-backed read command paths. In `--data-source auto` mode, covered commands check the local SQLite store before serving results; stale or missing resources trigger a bounded refresh, and refresh failures fall back to the existing local data with a warning. `--data-source local` never refreshes, and `--data-source live` reads the API without mutating the local store.

Set `{{if .Cache.EnvOptOut}}{{.Cache.EnvOptOut}}{{else}}{{envName .Name}}_NO_AUTO_REFRESH{{end}}=1` to disable the pre-read freshness hook while preserving the selected data source.
{{- if .FreshnessCommands}}

Covered command paths:
{{- range .FreshnessCommands}}
- `{{.}}`
{{- end}}
{{- end}}

JSON outputs that use the generated provenance envelope include freshness metadata at `meta.freshness`. This metadata describes the freshness decision for the covered command path; it does not claim full historical backfill or API-specific enrichment.
{{- end}}
{{- if .EndpointTemplateVars}}

## Runtime Endpoint

This CLI resolves endpoint placeholders at runtime, so one installed binary can target different tenants or API versions without regeneration.

Endpoint environment variables:
{{- range .EndpointTemplateVars}}
- `{{endpointTemplateEnvName .}}` resolves `{ {{- . -}} }`
{{- end}}

Base URL: `{{.BaseURL}}`
{{- if .GraphQLEndpointPath}}

GraphQL path: `{{.GraphQLEndpointPath}}`
{{- end}}
{{- end}}

## Health Check

```bash
{{.Name}}-pp-cli doctor
```

Verifies configuration{{if and (ne .Auth.Type "") (ne .Auth.Type "none")}}, credentials,{{end}} and connectivity to the API.

## Configuration

Config file: `{{.Config.Path}}`

Static request headers can be configured under `headers`; per-command header overrides take precedence.
{{- if or .Auth.EnvVarSpecs .Auth.EnvVars}}

Environment variables:

| Name | Kind | Required | Description |
| --- | --- | --- | --- |
{{- range .EndpointTemplateVars}}
| `{{envName $.Name}}_{{upper .}}` | endpoint | Yes |  |
{{- end}}
{{- if .Auth.EnvVarSpecs}}
{{- range .Auth.EnvVarSpecs}}
| `{{.Name}}` | {{.Kind}} | {{if .Required}}Yes{{else}}No{{end}} | {{.MarkdownDescription}} |
{{- end}}
{{- else}}
{{- range .Auth.EnvVars}}
| `{{.}}` | per_call | Yes |  |
{{- end}}
{{- end}}
{{- end}}

## Troubleshooting

{{- if .HasAuth}}
**Authentication errors (exit code 4)**
- Run `{{.Name}}-pp-cli doctor` to check credentials
{{- if .BearerRefresh.Enabled}}
- Run `{{.Name}}-pp-cli refresh-bearer` if a long-working public bearer token may have rotated
{{- end}}
{{- with $canonicalEnvVar}}
- Verify the environment variable is set: `echo ${{.Name}}`
{{- end}}

{{- end}}
**Not found errors (exit code 3)**
- Check the resource ID is correct
- Run the `list` command to see available items
{{- if and .Narrative .Narrative.Troubleshoots}}

### API-specific
{{range .Narrative.Troubleshoots}}
- **{{.Symptom}}** — {{.Fix}}
{{- end}}
{{- end}}
{{- if .UsesHTTP2DisabledTransport}}

## HTTP Transport

This CLI uses standard HTTP transport with HTTP/2 disabled for browser-facing endpoints. It does not require a resident browser process for normal API calls.
{{- else if .UsesBrowserHTTPTransport}}

## HTTP Transport

This CLI uses Chrome-compatible HTTP transport{{if .UsesBrowserHTTP3Transport}} over HTTP/3{{end}} for browser-facing endpoints. It does not require a resident browser process for normal API calls.
{{- end}}
{{- if .TrafficAnalysis}}

## Discovery Signals

This CLI was generated with browser-captured traffic analysis.
{{- if .TrafficAnalysis.TargetURL}}
- Target observed: {{.TrafficAnalysis.TargetURL}}
{{- end}}
- Capture coverage: {{.TrafficAnalysis.APIEntryCount}} API entries from {{.TrafficAnalysis.EntryCount}} total network entries
{{- if .TrafficAnalysis.Reachability}}
- Reachability: {{.TrafficAnalysis.Reachability}}
{{- end}}
{{- if .TrafficAnalysis.Protocols}}
- Protocols: {{join .TrafficAnalysis.Protocols ", "}}
{{- end}}
{{- if .TrafficAnalysis.AuthCandidates}}
- Auth signals: {{join .TrafficAnalysis.AuthCandidates "; "}}
{{- end}}
{{- if .TrafficAnalysis.Protections}}
- Protection signals: {{join .TrafficAnalysis.Protections ", "}}
{{- end}}
{{- if .TrafficAnalysis.GenerationHints}}
- Generation hints: {{join .TrafficAnalysis.GenerationHints ", "}}
{{- end}}
{{- if .TrafficAnalysis.CandidateCommands}}
- Candidate command ideas: {{join .TrafficAnalysis.CandidateCommands "; "}}
{{- end}}
{{- if .TrafficAnalysis.Warnings}}

Warnings from discovery:
{{- range .TrafficAnalysis.Warnings}}
- {{.}}
{{- end}}
{{- end}}
{{- end}}

---
{{- if or (gt (len .Sources) 1) (gt (len .DiscoveryPages) 0)}}

## Sources & Inspiration

This CLI was built by studying these projects and resources:
{{- if .DiscoveryPages}}

**Discovery** — API endpoints were mapped by observing traffic from:
{{range .DiscoveryPages}}
- {{.}}
{{- end}}
{{- end}}
{{- if gt (len .Sources) 1}}
{{range .Sources}}
- [**{{.Name}}**]({{.URL}}){{if .Language}} — {{.Language}}{{end}}{{if .Stars}} ({{.Stars}} stars){{end}}
{{- end}}
{{- end}}
{{- end}}

Generated by [CLI Printing Press](https://github.com/mvanhorn/cli-printing-press)
