Skip to content
Closed
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
58 changes: 58 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Command reference

Every command accepts `-h` / `--help` and prints its own usage.

## Authentication

| Command | Description |
|---|---|
| `promptless login` | Open a browser, complete the Clerk flow, and cache an API key |
| `promptless logout` | Remove the cached API key (and the file, if it ends up empty) |
| `promptless whoami` | Print the user and organizations associated with the current key |

Config-file location and env-var precedence are documented in [Configuration](configuration.md). The protocol between the CLI and the Promptless web app is documented in [CLI auth protocol](cli-auth-protocol.md).

## Suggestions

| Command | Description |
|---|---|
| `promptless suggestions [filters]` | List docs suggestions (default: 10 most recent, status=pr_open) |
| `promptless suggestions --stat [filters]` | Same list with a `git diff --stat`-style per-file breakdown |
| `promptless suggestions --id <id>` | Show a single suggestion in full, including the file list and stats |
| `promptless suggestions --json [filters]` | Emit JSON for scripting |

Filter flags: `--status` (repeatable; one of `ready`, `pr_open`, `published`, `closed`, or `any`), `--location`, `--trigger`, `--label`, `--assignee`, `--page`, `--since`, `--until`, `-q/--query` (dashboard-syntax filter expression). Limit flags: `-n/--limit`, `--all`, `--offset`. See [Suggestions](suggestions.md) for details.

## Local linting

| Command | Description |
|---|---|
| `promptless slop-cop <file>...` | Detect LLM prose tells in text files; runs entirely locally |
| `promptless slop-cop --debug <file>...` | Verbose debug output for rule authors |
| `promptless slop-cop --format <fmt> <file>...` | Force the input parser (`auto`, `text`, `markdown`, `mdx`, `pandoc`) |

Exit codes: `0` clean, `1` violations found, `2` argument error. `slop-cop` is the only command that does no network I/O.

## Web tools

| Command | Description |
|---|---|
| `promptless agentview <url>` | Fetch a page and print the markdown a coding agent will read |
| `promptless agentview <url> -o <file>` | Write the extracted markdown to a file instead of stdout |

## Shell integration

| Command | Description |
|---|---|
| `promptless completion zsh` | Print a zsh completion script |
| `promptless completion bash` | Print a bash completion script |
| `promptless completion fish` | Print a fish completion script |

Pipe the output into the appropriate location for your shell — e.g. `promptless completion zsh > ~/.zsh/completion/_promptless`.

## Global conventions

- Every command also responds to the short alias `pless`.
- Authenticated commands resolve the API key in this order: `$PROMPTLESS_CLI_API_SECRET`, then the cached config file. See [Configuration](configuration.md).
- Authenticated commands exit non-zero with a pointer back to `promptless login` if the key is missing or rejected — they never fall through to anonymous access.
- JSON output, where supported, is a single JSON value on stdout. Diagnostics go to stderr so `| jq` is safe.
82 changes: 82 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# promptless

A command-line companion for tech writers. The CLI surfaces docs work the Promptless platform has done on your behalf — detected prose tells, pending suggestions, agent-readable views of your published pages — without forcing you out of the terminal.

## How it works

Promptless runs as a hosted service that watches your docs and produces suggestions, audits, and analyses. The CLI is the local-side handle on that service. It authenticates once, then offers focused commands that each map to a single thing you would otherwise click through the web app to do.

This means you can:

- Triage open suggestions from your editor or terminal
- Lint your own drafts for LLM prose tells before committing
- See exactly what markdown a coding agent will read when it crawls a published page
- Drop authenticated calls into scripts and CI without juggling browser cookies

## Getting started

```
npm install -g github:Promptless/promptless-cli
promptless login
promptless whoami
```

`login` pops a browser, completes the Clerk handshake, and writes a long-lived API key to a config file under `~/.config/promptless/`. Every other command reads that file. See [Configuration](configuration.md) for path resolution and [Environment variables](environment-variables.md) for the overrides used by tests and staging.

## Commands

`promptless login`, `promptless logout`, `promptless whoami`, `promptless suggestions`, `promptless slop-cop`, `promptless agentview`, and `promptless completion`. See the full [command reference](commands.md).

The short alias `pless` is installed alongside `promptless` and accepts the same arguments.

## A day with promptless

Suppose you maintain the docs for a small developer tool. Here's what a typical morning might look like.

### Check what's waiting for you

```
$ promptless suggestions

ID STATUS REMOTE PR PAGE TRIGGER CREATED
sg_a1b2c pr_open Promptless/docs #3402 src/content/docs/docs/getting-started.mdx slack C0B2WNQ3CM9 38m ago
sg_d3e4f pr_open Promptless/docs #3398 src/content/docs/docs/integrations/linear… PR promptless#3398 5h ago
sg_g5h6i pr_open Promptless/runtime #3401 runtime/dispatch/prompts/notification_skill… slack C0B2WNQ3CM9 5h ago
...

Showing 10 of 23. Use --limit, --all, or filters to narrow.
```

Ten open suggestions, newest first. The default is intentionally short — see [Suggestions](suggestions.md) for filtering by docs location, trigger, status, label, or free-text query, and the `--stat` flag for a `git diff --stat`-style per-file breakdown.

### Read one in full

```
$ promptless suggestions --id sg_a1b2c
```

The list view is compact on purpose. `--id` shows the full body and suggested diff for a single suggestion.

### Draft a fix and lint it before you push

```
$ promptless slop-cop docs/intro.md
```

`slop-cop` flags the rhetorical and structural tells of LLM-generated prose so you can fix them before they ship. It is the only command that does no network I/O — pure local linting.

### See the page the way an agent will

```
$ promptless agentview https://docs.example.com/intro
```

Coding agents do not see your CSS or chrome — they see the markdown extracted from `<main>`. `agentview` prints exactly that, so you can audit what an agent will actually quote back.

## Configuration

The CLI stores a single piece of state: the cached API key. Path resolution, env-var overrides, and file permissions are documented in [Configuration](configuration.md).

Server endpoints (`app.gopromptless.ai` and `api.gopromptless.ai` by default) can be pointed at staging or a local stack via the variables in [Environment variables](environment-variables.md).

The login flow and the contract between the CLI and the Promptless web app is documented separately in [CLI auth protocol](cli-auth-protocol.md), which is primarily of interest if you are working on the CLI itself.
171 changes: 171 additions & 0 deletions docs/suggestions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# Suggestions

`promptless suggestions` lists the docs updates the Promptless platform has drafted for your organization — the same queue you see on the "suggestions pending review" page in the dashboard. Use it to triage open work, narrow in on a single page or trigger source, or pipe machine-readable output into another tool.

## Usage

```
promptless suggestions [options]
```

By default the command prints the 10 most recent **pr_open** suggestions for your organization, newest first. (An API key is scoped to a single org — see [Authentication](#authentication) below.)

```
$ promptless suggestions

ID STATUS REMOTE PR PAGE TRIGGER CREATED
sg_a1b2c pr_open Promptless/docs #3402 src/content/docs/docs/getting-started.mdx slack C0B2WNQ3CM9 38m ago
sg_d3e4f pr_open Promptless/docs #3398 src/content/docs/docs/integrations/linear… PR promptless#3398 5h ago
sg_g5h6i pr_open Promptless/runtime #3401 runtime/dispatch/prompts/notification_skill… slack C0B2WNQ3CM9 5h ago
...

Showing 10 of 23. Use --limit, --all, or filters to narrow.
```

The footer always reports how many suggestions matched in total, so the implicit limit is never silent.

Columns:

| Column | Source |
|---|---|
| `ID` | The suggestion's UUID, abbreviated. Pass the full or short ID to `--id` for detail. |
| `STATUS` | One of `ready`, `pr_open`, `published`, `closed`. Same statuses the dashboard uses. |
| `REMOTE` | The docs repo the suggestion targets, derived from `collection_name` + `docs_platform`. Blank if the suggestion's collection is not a git remote (e.g. ReadMe, Zendesk). |
| `PR` | The pull request number once the suggestion has opened one. Blank in `ready`. |
| `PAGE` | The first impacted file. Use `--stat` to see all of them with change types. |
| `TRIGGER` | A short label for what produced the suggestion: `slack <channel>`, `PR <repo>#<n>`, `web`, `api`. Pulled from the first trigger event. |
| `CREATED` | Relative time. Use `--json` for ISO timestamps. |

## Filters

The Promptless API returns every suggestion in the org and the CLI filters locally — the same way the dashboard does. Filters compose with AND; pass several to narrow further.

| Flag | Description |
|---|---|
| `--status <status>` | One of `ready`, `pr_open`, `published`, `closed`. Repeat the flag to include several (`--status ready --status pr_open`). Defaults to `pr_open`. Pass `--status any` to include every status. |
| `--location <name>` | Restrict by docs location. Matches `collection_name` (e.g. `docs-site`) or `docs_platform:collection_name` for disambiguation. |
| `--trigger <kind>` | Restrict by trigger source. Accepts `slack`, `web`, `api`, `github`, or a qualified form like `github:Promptless/docs` or `slack:C0B2WNQ3CM9`. |
| `--label <label>` | Restrict to suggestions carrying a label. Repeat for multiple labels (AND). |
| `--assignee <user>` | Restrict to suggestions assigned to a specific user. |
| `--page <path>` | Restrict to suggestions whose impacted files include this path. Glob patterns are honored (`--page 'src/content/docs/**'`). |
| `-q, --query <expr>` | Pass a raw query expression in the same syntax as the dashboard's filter box (e.g. `is:pr_open author:alice`). Composed with the structured flags above. |
| `--since <date>` | Only suggestions created on or after this date. Accepts ISO 8601 (`2026-04-01`) or relative offsets (`7d`, `2w`, `3mo`). |
| `--until <date>` | Only suggestions created on or before this date. |

```
$ promptless suggestions --status pr_open --status ready --trigger slack --since 7d

ID STATUS REMOTE PR PAGE TRIGGER CREATED
sg_a1b2c pr_open Promptless/docs #3402 src/content/docs/docs/getting-started.mdx slack C0B2WNQ3CM9 38m ago
sg_g5h6i ready Promptless/docs — src/content/docs/docs/intro.mdx slack C0B2WNQ3CM9 3h ago

Showing 2 of 2.
```

## Limit and pagination

The default limit of 10 is a soft cap meant to keep an invocation glanceable.

| Flag | Description |
|---|---|
| `-n, --limit <n>` | Show up to `n` suggestions instead of 10. |
| `--all` | Disable the limit and print every match. |
| `--offset <n>` | Skip the first `n` matches. Pairs with `--limit` to page through. |

```
$ promptless suggestions --limit 25
$ promptless suggestions --all --status any
$ promptless suggestions --limit 10 --offset 20 # third page of 10
```

When the result set exceeds the active limit, the footer says so:

```
Showing 10 of 23. Use --limit, --all, or filters to narrow.
```

The underlying API returns every suggestion in the org in a single response, so `--limit` and `--offset` truncate the rendered output rather than reducing what the CLI fetches.

## --stat

`--stat` extends the list view with the `git diff --stat`-style breakdown of every impacted file:

```
$ promptless suggestions --stat --limit 3

sg_a1b2c pr_open Promptless/docs #3402 Update copy: human ownership of authorship
src/content/docs/docs/getting-started.mdx MOD +12 -4
src/content/docs/docs/intro.mdx MOD +3 -1
3 files changed, 18 insertions(+), 6 deletions(-)

sg_d3e4f pr_open Promptless/docs #3398 Document Linear recording state
src/content/docs/docs/integrations/linear-integration.mdx MOD +24 -2
1 file changed, 24 insertions(+), 2 deletions(-)

sg_g5h6i pr_open Promptless/runtime #3401 Add guardrail requiring labeled links
runtime/dispatch/prompts/notification_skill.md.jinja MOD +8 -0
1 file changed, 8 insertions(+), 0 deletions(-)
```

Per-file line counts are not in the list response, so `--stat` fetches each shown suggestion's diff in turn. Expect roughly one extra request per row. Combine with `--limit` to keep it bounded; combining `--stat` with `--all` against a large org is slow and noisy.

The change-type tag (`MOD`, `ADD`, `DEL`) mirrors the dashboard's `MOD` / added / deleted badges.

## Showing one suggestion in full

The list view is intentionally compact. To read the full body of a single suggestion, look it up by ID:

```
$ promptless suggestions --id sg_a1b2c

sg_a1b2c — Update copy: human ownership of authorship
Status: pr_open
Remote: Promptless/docs
PR: https://github.com/Promptless/docs/pull/3402
Last SHA: c0ffee1a2b3c
Trigger: slack C0B2WNQ3CM9 — "<@U080S8KGDUP> All …" (and 1 other event)
Created: 2026-05-22T08:36:00Z (38 minutes ago)
Updated: 2026-05-22T08:54:00Z (20 minutes ago)
Labels: copy-edit, onboarding
Assignees: alice@example.com

Tighten the install section so it doesn't claim the docs team co-authors
the page with the LLM. Switch to first-person plural where it's the team
speaking, and drop the "we partnered with our AI assistant" line.

Files:
src/content/docs/docs/getting-started.mdx MOD +12 -4
src/content/docs/docs/intro.mdx MOD +3 -1

3 files changed, 18 insertions(+), 6 deletions(-)
```

`--id` ignores filter flags — it's a direct lookup. Pair with `--stat` is implied (detail view always shows the file list). If the ID does not exist or you do not have access to it, the command exits non-zero.

## JSON output

Pass `--json` to emit the matched suggestions as a single JSON array suitable for piping into `jq` or another tool. Field names mirror the API response (`id`, `title`, `status`, `pr_status`, `closed_at`, `impacted_files[]`, `trigger_events[]`, `collection_name`, `docs_platform`, `labels`, `assignees`, `last_sha`, `created_at`, `updated_at`). The implicit limit of 10 still applies in JSON mode unless you set `--limit` or `--all`.

```
$ promptless suggestions --json --status pr_open --limit 3 | jq '.[] | {id, title, pr: .trigger_events[0].metadata.source_pr_number}'
```

`--json --stat` additionally embeds the per-file diff stats under each `impacted_files[]` entry as `additions` and `deletions`.

## Exit codes

| Code | Meaning |
|---|---|
| 0 | At least one suggestion matched, or `--id` resolved. |
| 1 | No suggestions matched the filters, or `--id` was not found. |
| 2 | Argument error (unknown flag, malformed date, conflicting options). |

The `1` on "no matches" is intentional so that shell pipelines like `promptless suggestions --status ready && echo "nothing to triage"` work as expected.

## Authentication

`suggestions` is an authenticated command. It hits `api.gopromptless.ai` with the bearer key cached by `promptless login`, resolved through the precedence rules in [Configuration](configuration.md).

A Promptless API key is implicitly scoped to a single organization — the one whose dashboard generated it. The server derives the org from the bearer token, so `suggestions` does not take an `--org` flag and there is no way to query across organizations from one CLI session. To work against a different org, log out and back in (or point `$PROMPTLESS_CLI_API_SECRET` at a different key for a single command — see [Configuration](configuration.md)). `promptless whoami` always shows which org the current key resolves to.

If the cached key is missing or rejected the command exits non-zero with a pointer back to `promptless login` — it does not silently fall through to anonymous access.