---
name: pp-judgeme
description: "A completeness-verified Judge.me review corpus with explicit populations and syndication-aware exports. Trigger phrases: `sync all Judge.me reviews safely`, `export published Judge.me reviews`, `count hidden Judge.me reviews`, `deduplicate syndicated review bodies`, `use Judge.me`, `run Judge.me`."
author: "Cathryn Lavery"
license: "Apache-2.0"
argument-hint: "<command> [args] | install cli|mcp"
allowed-tools: "Read Bash"
metadata:
  openclaw:
    requires:
      bins:
        - judgeme-pp-cli
    install:
      - kind: go
        bins: [judgeme-pp-cli]
        module: github.com/mvanhorn/printing-press-library/library/marketing/judgeme/cmd/judgeme-pp-cli
---

# Judge.me — Printing Press CLI

## Prerequisites: Install the CLI

This skill drives the `judgeme-pp-cli` binary. **You must verify the CLI is installed before invoking any command from this skill.** If it is missing, install it first:

1. Install via the Printing Press installer. It defaults binaries to `$HOME/.local/bin` on macOS/Linux and `%LOCALAPPDATA%\Programs\PrintingPress\bin` on Windows:
   ```bash
   npx -y @mvanhorn/printing-press-library install judgeme --cli-only
   ```
2. Verify: `judgeme-pp-cli --version`
3. Ensure the reported install directory is on `$PATH` for the agent/runtime that will invoke this skill.

If the `npx` install fails (no Node, offline, etc.), fall back to a direct Go install (requires Go 1.26.6 or newer). This installs into `$GOPATH/bin` (default `$HOME/go/bin`), so add that directory to `$PATH` instead:

```bash
go install github.com/mvanhorn/printing-press-library/library/marketing/judgeme/cmd/judgeme-pp-cli@latest
```

If `--version` reports "command not found" after install, the runtime cannot see the binary directory on `$PATH`. Do not proceed with skill commands until verification succeeds.

Wrap the full Judge.me API while defending review workflows against the silent 10,000-row pagination loop. Sync once into a documented SQLite mirror, then export, count, and deduplicate published or internal review populations with provenance on every agent response.

## When to Use This CLI

Use this CLI for Judge.me review synchronization, moderation inspection, export, storefront-widget access, and syndication-aware customer-language analysis. Prefer the local review mirror when exact corpus completeness or repeatable filtering matters.

## Anti-triggers

Do not use this CLI for:
- Do not use this CLI to infer which syndicated product association is the true one.
- Do not use raw `reviews index` pagination as proof of full-corpus completeness.
- Do not use mutation commands without reviewing the dry-run and passing the explicit apply flag.

## Unique Capabilities

These capabilities aren't available in any other tool for this API.

### Verified local corpus
- **`sync`** — Mirror the complete review corpus and refuse success when unique IDs do not equal Judge.me's live count.

  _Use this before any analysis that depends on corpus completeness._

  ```bash
  judgeme-pp-cli sync --resources reviews --full --max-pages 1 --agent
  ```
- **`reviews export`** — Export explicit published, hidden, pending, or all populations as JSON or CSV.

  _Use this to hand a bounded, provenance-labeled review slice to downstream analysis tools._

  ```bash
  judgeme-pp-cli reviews export --population published --rating 5 --csv --dry-run
  ```

### Population integrity
- **`reviews populations`** — Count storefront-visible and internal moderation populations with unambiguous labels.

  _Use this whenever published-vs-hidden population differences affect a report or decision._

  ```bash
  judgeme-pp-cli reviews populations --agent --dry-run
  ```
- **`reviews syndication`** — Find identical normalized review bodies attached to multiple products.

  _Use this before attributing customer language to a specific SKU or product._

  ```bash
  judgeme-pp-cli reviews syndication --population all --min-products 2 --agent --dry-run
  ```
- **`reviews unique-bodies`** — Return one deterministic representative per normalized review body while retaining source row counts.

  _Use this when independent customer voices matter more than API row count._

  ```bash
  judgeme-pp-cli reviews unique-bodies --population published --agent --dry-run
  ```

## Command Reference

**private-replies** — Manage private replies

- `judgeme-pp-cli private-replies` — Create a private email reply to a [Judge.me](http://judge.me/) review privately via your app interface.

**replies** — Manage replies

- `judgeme-pp-cli replies` — Create a reply to a Judge.me review on the public [Judge.me](http://judge.me/) review widget via your app interface.

**reviewers** — Manage reviewers

- `judgeme-pp-cli reviewers data-request` — Data Request
- `judgeme-pp-cli reviewers get` — Get information of the reviewers such as name and email.
- `judgeme-pp-cli reviewers update` — Create or update a reviewer via your app interface.

**reviews** — You can use the reviews endpoints to access review information. Common use cases include:
- Synchronize and display reviews in your admin dashboard.
- Get event of new reviews (via webhook) to perform an action on your side.
- Let users manage reviews (publish/hide) on your side.
*Note: these endpoints respond **raw** review information, which may include **unpublished reviews**, or review content that is **not sanitized** yet (so risks of XSS).
To render review content on storefront, please use widget endpoints instead.

- `judgeme-pp-cli reviews create` — Create a web review in background
- `judgeme-pp-cli reviews get` — Get info of a specific review.
- `judgeme-pp-cli reviews index` — Get info of reviews of a product. If `product_id` is not provided, return all product and store reviews of that store.
- `judgeme-pp-cli reviews reviewers-count` — Get count of reviews for a specific product or reviewer.
- `judgeme-pp-cli reviews update` — Publish or hide a Judge.me review via your app interface.

**settings** — Manage settings

- `judgeme-pp-cli settings` — Get multiple settings values of the store in [Judge.me](http://judge.

**shops** — Manage shops

- `judgeme-pp-cli shops comments-create` — Create a checkout comment. Available in Checkout Comments app only.
- `judgeme-pp-cli shops destroy` — Uninstall the store from Judge.me
- `judgeme-pp-cli shops get` — Get the basic information of the store such as [Judge.me](http://judge.
- `judgeme-pp-cli shops update` — Update store information

**webhooks** — Subscribe to an event happens in Judge.me. Judge.me will send a POST request to the registered URL containing relevant information for each event.

Common webhook keys:
1. **review/created** or **review/created_fail**: to know when a review is created, or not.
2. **review/updated**: to know when a review is updated in Judge.me. In particular, when a review is:
- curated or mass curated
- pinned/featured in carousel
- moved to another product
- edited from admin or user profile
- verified review via request emails
- added/hidden/shown review photos from admin or user profile
3. Widgets update webhooks (e.g. **widget/settings/updated**): to know when Judge.me updates a widget.
***Note**: You can learn how to verify webhooks from Judge.me following this [guide](https://help.judge.me/en/articles/8299679-verifying-webhooks-from-judge-me).

- `judgeme-pp-cli webhooks bulk-create` — Bulk Create
- `judgeme-pp-cli webhooks create` — Create a webhook in Judge.me with a `key` and a `url`. When an event associated with `key` happens, Judge.
- `judgeme-pp-cli webhooks destroy` — Delete
- `judgeme-pp-cli webhooks get` — Get
- `judgeme-pp-cli webhooks index` — Index
- `judgeme-pp-cli webhooks update` — Update

**widgets** — Manage widgets

- `judgeme-pp-cli widgets all-reviews-count` — Return a single total number of product and store reviews.
- `judgeme-pp-cli widgets all-reviews-page` — All Reviews Page is a dedicated page to showcase all product and store reviews all in one place.
- `judgeme-pp-cli widgets all-reviews-rating` — Return a single number of average rating of product reviews and store reviews.
- `judgeme-pp-cli widgets checkout-comments` — Return Checkout Comments widget for a product (for Checkout Comments app only).
- `judgeme-pp-cli widgets featured-carousel` — Reviews Carousel is usually placed on the homepage to showcase specific reviews featured by the store.
- `judgeme-pp-cli widgets html-miracle` — Return special HTML that helps show essential parts of widgets before the JS and CSS files are loaded.
- `judgeme-pp-cli widgets preview-badge` — Preview Badge is usually placed below product titles on product pages or inside product thumbnails on collection pages.
- `judgeme-pp-cli widgets product-review` — Review Widget is usually placed at the bottom of each product page, displaying all reviews of a product.
- `judgeme-pp-cli widgets reviews-tab` — Floating Reviews Tab display all product and store reviews via a floating button on any pages.
- `judgeme-pp-cli widgets settings` — Return widget settings of the shop, under HTML format, containing a `<script>` tag and a `<style>` tag.
- `judgeme-pp-cli widgets shop-reviews-count` — Return a single total number of store reviews.
- `judgeme-pp-cli widgets shop-reviews-rating` — Return a single number of average rating of store reviews.
- `judgeme-pp-cli widgets verified-badge` — Verified Reviews Count Badge displays the number of verified published reviews.


## Freshness Contract

This printed CLI owns bounded freshness only for registered store-backed read command paths. In `--data-source auto` mode, those paths check `sync_state` and may run a bounded refresh before reading local data. `--data-source local` never refreshes. `--data-source live` reads the API and does not mutate the local store. Set `JUDGEME_NO_AUTO_REFRESH=1` to skip the freshness hook without changing source selection.

Covered paths:

- `judgeme-pp-cli reviews`
- `judgeme-pp-cli reviews get`
- `judgeme-pp-cli reviews list`
- `judgeme-pp-cli reviews search`
- `judgeme-pp-cli settings`
- `judgeme-pp-cli settings get`
- `judgeme-pp-cli settings list`
- `judgeme-pp-cli settings search`
- `judgeme-pp-cli webhooks`
- `judgeme-pp-cli webhooks get`
- `judgeme-pp-cli webhooks list`
- `judgeme-pp-cli webhooks search`
- `judgeme-pp-cli widgets`
- `judgeme-pp-cli widgets get`
- `judgeme-pp-cli widgets list`
- `judgeme-pp-cli widgets search`
- `judgeme-pp-cli widgets-all-reviews-count`
- `judgeme-pp-cli widgets-all-reviews-count get`
- `judgeme-pp-cli widgets-all-reviews-count list`
- `judgeme-pp-cli widgets-all-reviews-count search`
- `judgeme-pp-cli widgets-all-reviews-page`
- `judgeme-pp-cli widgets-all-reviews-page get`
- `judgeme-pp-cli widgets-all-reviews-page list`
- `judgeme-pp-cli widgets-all-reviews-page search`
- `judgeme-pp-cli widgets-all-reviews-rating`
- `judgeme-pp-cli widgets-all-reviews-rating get`
- `judgeme-pp-cli widgets-all-reviews-rating list`
- `judgeme-pp-cli widgets-all-reviews-rating search`
- `judgeme-pp-cli widgets-product-review`
- `judgeme-pp-cli widgets-product-review get`
- `judgeme-pp-cli widgets-product-review list`
- `judgeme-pp-cli widgets-product-review search`

When JSON output uses the generated provenance envelope, freshness metadata appears at `meta.freshness`. Treat it as current-cache freshness for the covered command path, not a guarantee of complete historical backfill or API-specific enrichment.

### Finding the right command

When you know what you want to do but not which command does it, ask the CLI directly:

```bash
judgeme-pp-cli which "<capability in your own words>"
```

`which` resolves a natural-language capability query to the best matching command from this CLI's curated feature index. Exit code `0` means at least one match; exit code `2` means no confident match — fall back to `--help` or use a narrower query.

## Recipes

### Narrow a published corpus for an agent

```bash
judgeme-pp-cli reviews export --population published --agent --select meta.source,meta.synced_at,results.id,results.rating,results.body
```

Return only storefront-visible review fields needed for downstream analysis.

### Measure population differences

```bash
judgeme-pp-cli reviews populations --agent
```

Compare all, published, pending, and hidden review populations.

### Find bundle syndication

```bash
judgeme-pp-cli reviews syndication --min-products 2 --agent
```

Identify one body hash associated with multiple products.

### Export independent voices

```bash
judgeme-pp-cli reviews unique-bodies --population published --csv
```

Produce one representative row per normalized review body.

## Auth Setup

Set JUDGEME_API_KEY to the private token and JUDGEME_SHOP_DOMAIN to the store's myshopify.com domain. The private token is sent only in the X-Api-Token header and is redacted from logs; it is never placed in a request URL.

Run `judgeme-pp-cli doctor` to verify setup.

## Agent Mode

Add `--agent` to any command. Expands to: `--json --compact --no-input --no-color --yes`.

- **Pipeable** — JSON on stdout, errors on stderr
- **Filterable** — `--select` keeps a subset of fields. Dotted paths descend into nested structures; arrays traverse element-wise. Critical for keeping context small on verbose APIs:

  ```bash
  judgeme-pp-cli reviewers get mock-value --agent --select id,name,status
  ```
- **Previewable** — `--dry-run` shows the request without sending
- **Offline-friendly** — sync/search commands can use the local SQLite store when available
- **Non-interactive** — never prompts, every input is a flag
- **Explicit retries** — use `--idempotent` only when an already-existing create should count as success, and use `--ignore-missing` only when a missing delete target should count as success

### Response envelope

Commands that read from the local store or the API wrap output in a provenance envelope:

```json
{
  "meta": {"source": "live" | "local", "synced_at": "...", "reason": "..."},
  "results": <data>
}
```

Parse `.results` for data and `.meta.source` to know whether it's live or local. A human-readable `N results (live)` summary is printed to stderr only when stdout is a terminal AND no machine-format flag (`--json`, `--csv`, `--compact`, `--quiet`, `--plain`, `--select`) is set — piped/agent consumers and explicit-format runs get pure JSON on stdout.

## Paths and state

Agents should treat the CLI's path resolver as part of the runtime contract:

- Use `--home <dir>` for one invocation, or set `JUDGEME_HOME=<dir>` to relocate all four path kinds under one root.
- Use per-kind env vars only when a specific kind must diverge: `JUDGEME_CONFIG_DIR`, `JUDGEME_DATA_DIR`, `JUDGEME_STATE_DIR`, `JUDGEME_CACHE_DIR`.
- Resolution order is per-kind env var, `--home`, `JUDGEME_HOME`, XDG (`XDG_CONFIG_HOME`, `XDG_DATA_HOME`, `XDG_STATE_HOME`, `XDG_CACHE_HOME`), then platform defaults.
- `config` contains settings like `config.toml` and profiles. `data` contains `credentials.toml`, `data.db`, cookies, and auth sidecars. `state` contains persisted queries, jobs, and `teach.log`. `cache` contains regenerable HTTP/cache files.
- Stored secrets live in `credentials.toml` under the data dir. Existing legacy `config.toml` secrets are read for compatibility and leave `config.toml` on the first auth write.
- Run `judgeme-pp-cli doctor --fail-on warn` to surface path and credential-location warnings. `agent-context` exposes a schema v4 `paths` block for agents that need the resolved dirs.
- For MCP, pass relocation through the MCP host config. The MCP binary does not inherit CLI flags:

  ```json
  {
    "mcpServers": {
      "judgeme": {
        "command": "judgeme-pp-mcp",
        "env": {
          "JUDGEME_HOME": "/srv/judgeme"
        }
      }
    }
  }
  ```

Fleet precedence: an inherited per-kind env var overrides an explicit `--home` for that kind. Use `JUDGEME_HOME` or per-kind vars as durable fleet levers, and use `--home` only for a single invocation. Relocation is not reversible by unsetting env vars; move files manually before clearing `JUDGEME_HOME`, or `doctor` will not find credentials left under the former root.

## Automatic learning

This CLI ships a self-capturing learning loop. The CLI does its own bookkeeping: every invocation is journaled locally, a failed flag followed by a corrected retry auto-derives a `flag_alias` candidate, and a `teach` on a query family without a playbook auto-synthesizes a `playbook_candidate` from the session's journal. Your job is judgment only: `recall` first, act on surfaced candidates, `teach` the final answer, `playbook amend` when you observe a correction. You never record failures by hand.

### Step 1: `recall` before any discovery

Before list/search/drill commands on a new user question, run:

```bash
judgeme-pp-cli recall "<user's question>" --agent
```

The response envelope:

```json
{
  "query": "...",
  "normalized": "<normalized form>",
  "query_entities": ["..."],
  "found": true | false,
  "match_score": 0.0,
  "results": [
    { "resource_id": "...", "resource_type": "...", "venue": "...",
      "confidence": 2, "entity_match": "exact|partial|unknown",
      "source": "taught|preseed|pattern", "warnings": ["..."] }
  ],
  "mismatches": [ /* only when --debug-mismatches */ ],
  "warnings": [ /* top-level */ ],
  "candidates": [
    { "id": 12, "class": "flag_alias | playbook_candidate",
      "summary": "...", "sightings": 3, "last_seen": "...",
      "rationale": "...",
      "next_action": ["<trial command>", "judgeme-pp-cli learnings confirm 12"] }
  ],
  "playbook": {
    "query_family": "...",
    "playbook": {
      "steps": [ { "cmd": "<command with {slot} substitution>", "purpose": "..." } ],
      "entity_slots": ["$ENTITY"],
      "expected_tool_calls": 3
    },
    "slots_resolved": { "$ENTITY": { "token": "<live token>", "canonical": "<canonical>" } },
    "notes": "<workarounds + gotchas for this query family>"
  },
  "notes": "<duplicate surface for non-playbook callers>"
}
```

Empty-store short-circuit: if the store has no learnings, playbooks, or candidates yet (recall finds nothing and `learnings list` and `learnings candidates` are both empty), skip recall for the rest of this session instead of taxing every query; resume recall-first once something has been taught.

### Step 2: decision tree

Read `candidates`, `playbook`, `notes`, `results[0]`, and warnings in that order:

```
if Candidates present (warnings include "candidates_present"):
    -> candidates are try-then-confirm, never facts. Follow each candidate's
       two-step next_action verbatim: run the trial command first, then run
       `learnings confirm <id>` only after the trial verified the behavior.
       Reject a wrong candidate with `learnings reject <id>`.
    -> NEVER re-teach something recall surfaced as a candidate; confirm or
       reject that candidate instead of teaching a duplicate.
    -> candidates ride alongside playbooks and resource hits, not instead of
       them; continue with the branches below after acting on them.

if Playbook present:
    -> READ Playbook.notes verbatim FIRST (workarounds + gotchas the CLI surface doesn't expose)
    -> replay Playbook.steps in order, substituting Playbook.slots_resolved entries
       for the entity slot tokens. If a step's slot is unresolved, fall back to
       discovery for that step only.
    -> the Playbook's expected_tool_calls is a budget; if you find yourself running
       materially more, record the divergence via `judgeme-pp-cli playbook amend`
       at end-of-session.

elif Notes present (no Playbook):
    -> read Notes verbatim before any discovery step; they carry known gotchas
       for this query family even when no structured choreography exists yet.

elif Found AND Results[0].EntityMatch == "exact" AND Results[0].Confidence >= 2:
    -> skip discovery; fetch live data for Results[*].ResourceID in parallel

elif Found AND Results[0].EntityMatch == "partial":
  