Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ on:
branches: ["**"]
pull_request:
workflow_dispatch:
# The catalogue count drifts because the SERVER moves, not because this repo does —
# so a check that only runs on push cannot see it. Measured 2026-09-18: the last CI
# run here was 2026-08-16, and by then prowl.chat had gone 448 -> 444 while this
# package still published 448 on npm and in its README. A weekly tick is what turns
# "somebody has to remember" into "the repository notices".
schedule:
- cron: "17 6 * * 1"
# Callable, so `release.yml` can depend on it. Re-implementing these checks as
# steps inside the release is how a red suite stops being able to stop a publish:
# a separate workflow going red cannot fail another one. The sibling repository
Expand Down
61 changes: 61 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# AGENTS.md

Instructions for an AI agent working in this repository. `CONTRIBUTING.md` is the human
version and takes precedence where the two ever disagree; this file exists because the
[agent-plugins.org](https://agent-plugins.org) convention expects it at the repository root
and because an agent reads first and asks second.

## What this is

`@prowl-ai/cli` — the command-line client for the [Prowl MCP](https://prowl.chat). One
endpoint, 444 market-intelligence tools, billed pay-as-you-go from a USD wallet. Node, ESM,
no build step: `src/` is what ships.

## The gate, before you claim anything

```bash
npm test # node --test, offline BY DESIGN — no key, no network
npm run check:tools # the stated catalogue count against what prowl.chat serves
```

`npm test` must pass with no API key and no network. `check:tools` deliberately reaches the
network and is a separate command and a separate CI job; an unreachable server exits 0 with
`UNKNOWN`, never as drift. **A check that could not ask has learned nothing, and one that
reports that as a failure gets re-run instead of read.**

## The rule behind most review comments

**A number or a name is fetched, not remembered.** This CLI's banner said `408` tools for
two releases while the server served `448`, and in September 2026 it said `448` while the
server served `444` — twice confident, twice wrong. `API_TOOL_COUNT` in `src/config.js` is
the one place the catalogue size is stated; the README and `package.json` description repeat
it and `check:tools` compares all three against the server. Keep it one place, checked.

The same trap has a second door: CI runs on push, and this number drifts because the
**server** moves, not because the repository does. That is why the workflow also runs on a
weekly schedule — a quiet repository must still notice.

## The command surface is a published contract

`plugins/prowl-cli` in [`PROWL-AI/prowl-skill`](https://github.com/PROWL-AI/prowl-skill)
documents this CLI, and its `scripts/check-cli.js` reads **this package's published tarball**
on every CI run, diffing the verbs in `src/index.js`'s dispatcher and the `EXIT` map in
`src/errors.js` against what that page states.

So adding, renaming or removing a verb, a flag or an exit code turns that repository's CI red
until its page is updated. That is the check working, not a nuisance. Say so in the PR
description and expect a matching change over there.

## Releasing

Bump `version` in `package.json` **in the same PR**, with a matching `## vX.Y.Z` section in
`CHANGELOG.md`. A merge to `master` that changes the version cuts the tag automatically and
`release.yml` publishes; a merge that does not bump publishes nothing.

## What not to do

- Do not hardcode a tool count, a tool name or an endpoint anywhere but its one source.
- Do not make `npm test` need the network or a key — that is the property that makes it
runnable by anyone, including you.
- Do not print, log or commit an API key. The CLI reads `PROWL_API_KEY` from the
environment and nothing here should ever echo it.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# @prowl-ai/cli

**Prowl CLI** — one command-line client for the [Prowl MCP](https://prowl.chat): **448 market-intelligence tools** across 15 providers (SEO & backlinks, 60+ SERP engines, ads, web scraping, AI) plus the full Prowl research pipeline, billed pay-as-you-go from a USD wallet.
**Prowl CLI** — one command-line client for the [Prowl MCP](https://prowl.chat): **444 market-intelligence tools** across 15 providers (SEO & backlinks, 60+ SERP engines, ads, web scraping, AI) plus the full Prowl research pipeline, billed pay-as-you-go from a USD wallet.

[![npm](https://img.shields.io/npm/v/@prowl-ai/cli?style=flat-square)](https://www.npmjs.com/package/@prowl-ai/cli)
[![Node](https://img.shields.io/badge/node-%3E%3D18-339933?style=flat-square)](https://nodejs.org)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@prowl-ai/cli",
"version": "0.2.1",
"description": "Prowl CLI — command-line client for the Prowl MCP: 448 market-intelligence tools (SEO, ads, SERP, scraping, AI) on pay-as-you-go USD wallet billing.",
"description": "Prowl CLI — command-line client for the Prowl MCP: 444 market-intelligence tools (SEO, ads, SERP, scraping, AI) on pay-as-you-go USD wallet billing.",
"type": "module",
"bin": {
"prowl": "./src/index.js"
Expand Down
2 changes: 1 addition & 1 deletion src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const VERSION = JSON.parse(readFileSync(new URL("../package.json", import
// what prowl.chat serves, and CI fails the build when they part. The repository
// said 408 for two releases while the server served 448; a number restated in
// prose with nothing checking it is a number that will drift.
export const API_TOOL_COUNT = 448;
export const API_TOOL_COUNT = 444;

/**
* Resolve the API key from, in order: an explicit `--key`, `PROWL_API_KEY`, and
Expand Down
Loading