Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ dist/
# this repo's own dogfooding digests — end-user repos should commit these
docs/promote/digests/

# internal-only product spec — not for npm or public history
docs/prd.md

# claude code
.claude/

Expand Down
104 changes: 95 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@
<p><strong>Turn repeated AI review comments into durable repository memory.</strong></p>

<p>
<a href="#who-this-is-for">Audience</a> ·
<a href="#why-promote-cli">Why</a> ·
<a href="#how-it-works">How</a> ·
<a href="#quick-start">Quick start</a> ·
<a href="#what-makes-it-different">Features</a> ·
<a href="#examples">Examples</a> ·
<a href="#privacy--security">Privacy</a>
</p>
<p>
<a href="#cost--mode-trade-off">Cost</a> ·
<a href="#cli-reference">CLI</a> ·
<a href="#faq">FAQ</a> ·
<a href="#roadmap">Roadmap</a>
</p>

Expand All @@ -25,7 +31,18 @@

<br />

CodeRabbit, Copilot, and Claude review your PRs — and the same suggestions keep coming back. **promote-cli** mines repeated review comments across your PR history, clusters them into patterns, and helps you promote each into a rule your AI tools will read on the next review.
CodeRabbit, Copilot, Claude, Cursor, and other AI reviewers can be useful, but the same suggestions often come back across PRs.

**promote-cli** scans your PR review history, clusters repeated comments, and helps you promote those patterns into durable repo memory:

- `CLAUDE.md` / `AGENTS.md`
- GitHub Copilot instructions
- Cursor / Windsurf / Gemini rules
- path-scoped rules
- ADRs
- test recommendations

It runs locally, uses your own LLM API key, and asks for human approval before writing.

<div align="center">

Expand All @@ -46,6 +63,19 @@ promote scan --since 30d

<br />

## Who this is for

promote-cli is for teams that:

- use AI reviewers such as CodeRabbit, Copilot, Claude, Cursor, Greptile, Qodo, Devin, or Sourcery
- keep repo instructions in `CLAUDE.md`, `AGENTS.md`, `.github/copilot-instructions.md`, `.cursor/rules/`, or similar files
- see the same review comments repeated across PRs
- want a human-approved way to turn repeated review feedback into durable rules, ADRs, or tests

It is probably not useful if your repo does not use PR review comments or coding-agent instruction files.

<br />

## Why promote-cli

AI review tools leave comments on PRs. Developers resolve them and move on. The decision disappears into a closed PR thread.
Expand All @@ -56,7 +86,7 @@ If the same comment appears next week, the team pays the same review cost again.

> *"The human reviewer's role is no longer to trace code details, but to measure the distance between decisions and implementation."*

The name *promote* reflects that shift: review comments aren't disposable noise — they're **knowledge waiting to be elevated** into your repo's durable memory. The decision still yours is *where* it belongs.
The name *promote* reflects that shift: review comments aren't disposable noise — they're **knowledge waiting to be elevated** into your repo's durable memory. The decision is still yours: whether and where each pattern belongs.

| | Without any tool | Hand-writing AGENTS.md | With promote-cli |
| ---------------------------- | ------------------------- | -------------------------- | ------------------------------- |
Expand Down Expand Up @@ -107,7 +137,7 @@ promote init
promote scan --since 30d
```

**3. Review.** Walk through each candidate — promote or skip per item. Approved ones land in your chosen target file immediately.
**3. Review.** Walk through each candidate — promote or skip per item. Approved ones land in your chosen target file immediately. See [Examples](#examples) for what a real digest and patch look like.

```
─── Candidate 1/7 ───
Expand Down Expand Up @@ -173,15 +203,43 @@ Output is localized per `language.preferredOutput` in `.promote.yml` (en / ko /

<br />

## Examples

Want to see representative output from real scans before installing?

- [Sample quick digest (trpc/trpc, OpenAI `quick`)](examples/digests/sample-quick.md)
- [Sample broad digest (trpc/trpc, Anthropic `broad`)](examples/digests/sample-broad.md)
- [`CLAUDE.md` patch example](examples/patches/claude-rule.patch)
- [Cursor rule patch example](examples/patches/cursor-rule.patch)

Both digests come from real `promote scan` runs against the public [`trpc/trpc`](https://github.com/trpc/trpc) repository.

<br />

## Privacy & security

promote-cli is designed as a local BYOK tool.

- **No hosted backend.** Your comments are never proxied through a promote server.
- **Your provider key.** LLM calls go directly from your machine or CI runner to OpenAI, Anthropic, or Google.
- **Secret redaction.** Tokens, AWS keys, JWTs, and similar secrets are stripped before any LLM call (`privacy.redactSecrets: true` by default).
- **No diff hunks by default.** `privacy.sendDiffHunksToLLM` defaults to `false` — comments are analyzed without sending the surrounding code diff.
- **Human approval.** In interactive mode, every candidate is reviewed before anything is written.
- **CI guardrail.** Headless mode can open a PR, but candidates flagged `needs_human_decision` are never auto-applied.

See [`SECURITY.md`](SECURITY.md) for how to report a vulnerability.

<br />

## Cost & mode trade-off

Measured on trpc/trpc, 120-day window, 380 actionable AI comments:

| Mode + provider | Candidates | Cost | Wall time | Output style |
| -------------------------------------- | ---------- | ------- | --------- | --------------------------------------------- |
| OpenAI `quick` (gpt-4.1-mini + nano) | **24** | $0.07 | 2m 14s | Narrow, file-specific |
| OpenAI `broad` (gpt-4.1-mini cluster) | 8 | $0.10 | 2m 39s | Core conventions only — subset of Anthropic |
| **Anthropic `broad` (Haiku 4.5)** | **21** | $0.47 | 8m 17s | **Convention / principle / ADR mix** |
| Mode + provider | Candidates | Cost | Wall time | Output style |
| --------------------------------- | ---------- | ----- | --------- | ------------------------------------ |
| OpenAI `quick` | **24** | $0.07 | 2m 14s | Narrow, file-specific |
| OpenAI `broad` | 8 | $0.10 | 2m 39s | Core conventions only |
| **Anthropic `broad` (Haiku 4.5)** | **17** | $0.45 | 4m 55s | Convention / principle / ADR mix |

Picking a mode by cadence:

Expand All @@ -191,7 +249,7 @@ Picking a mode by cadence:
| **Monthly** | Anthropic `broad` | Higher cost but extracts conventions worth memorializing |
| **Quarterly / sprint-end** | Anthropic `broad` + optional `--mode quick` follow-up | Combined coverage: principles from broad, code-level from quick |

No Anthropic key? OpenAI `broad` is the "budget" alternative — reliably catches the 6–8 core repo-wide conventions at ~5× lower cost than Anthropic broad, though without the full depth (20+ conventions including ADR-worthy decisions).
No Anthropic key? OpenAI `broad` is the "budget" alternative — reliably catches the 6–8 core repo-wide conventions at ~5× lower cost than Anthropic broad, though without the same depth of convention / principle / ADR-style candidates.

Full breakdown with examples from each mode → [docs/clustering.md](docs/clustering.md).

Expand Down Expand Up @@ -292,6 +350,34 @@ promote scan \

<br />

## FAQ

### Does promote-cli replace code review?

No. It does not review new code. It mines review history and proposes durable memory updates for patterns that already appeared in PR comments.

### Does it write to my repo automatically?

Interactive mode asks for approval per candidate. Headless CI mode can open a single bundled PR, but candidates that require human judgment (`needs_human_decision`) are never auto-applied — they stay in the digest for local review with `promote review`.

### Does it send my source code to an LLM?

By default, promote-cli analyzes review comments without sending the surrounding diff hunks (`privacy.sendDiffHunksToLLM: false`). You can opt into sending diff context if your team wants higher classification accuracy.

### Does it work with private repositories?

Yes, as long as your GitHub token can read the repository's PR review comments. The tool itself is local-first and never sends comments to a promote-hosted server.

### Which AI tools does it support?

It can write to memory targets used by Claude Code, OpenAI Codex, GitHub Copilot, Cursor, Windsurf, and Gemini CLI. See [`docs/config.md`](docs/config.md) for the full targets matrix.

### Is this a hosted service?

No. promote-cli runs entirely on your machine or your own CI runner. LLM calls go from your environment to your configured provider using your key.

<br />

## Roadmap

**Shipping today** — Personal CLI, multi-tool routing, hybrid clustering, human reply/reaction signal, filter transparency, stable IDs, secret redaction, i18n digest (en / ko / ja), atomic headless `--create-pr` flow (cuts from base, rollback on failure, LLM-filled PR template, gh/octokit dual transport), GitHub Action template for scheduled weekly digest PRs.
Expand Down
30 changes: 30 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Security Policy

## Supported versions

| Version | Supported |
| ------- | --------- |
| 0.7.x | ✅ |
| < 0.7 | ❌ |

## Reporting a vulnerability

Please report security issues privately through GitHub Security Advisories
rather than a public issue:

<https://github.com/gyulsbox/promote/security/advisories/new>

We aim to acknowledge reports within 7 days.

## Scope

promote-cli is a local CLI that calls third-party LLM providers with your own
API key. Reports that affect installed users or CI consumers are in scope:

- Issues that could exfiltrate API keys, repository tokens, or PR content
- Bypasses of secret redaction (`privacy.redactSecrets`)
- Issues that cause unintended writes to your repository
- Supply-chain issues in the published npm package

Issues in the third-party services we call (OpenAI, Anthropic, Google,
GitHub) should be reported to those providers directly.
6 changes: 3 additions & 3 deletions docs/clustering.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Two paths for grouping repeated comments, with very different output character.
- "Internal implementation details must not be imported from `src/`; use public unstable API exports"
- "Cache invalidation must include generator/tsconfig/artifact existence checks"
- "SSE retry budget must not be consumed on initial connection; exclude AbortError"
- **Cost / time**: ~$0.47 / ~8 min on 380 comments (Anthropic, concurrency=1)
- **Cost / time**: ~$0.45 / ~5 min on 380 comments (Anthropic, concurrency=1)
- **Provider recommendation: Anthropic Claude.** OpenAI broad on tier-1 keys hits rate limits on the larger models (gpt-4.1, gpt-4o) and the mini variants don't produce reliable semantic groupings; Anthropic Haiku 4.5 handles both depth and reliability in one tier.

## Picking a mode
Expand All @@ -52,6 +52,6 @@ trpc/trpc, 120d window, 380 actionable AI comments:
| OpenAI quick (gpt-4.1-mini + nano) | **24** | $0.07 | 2m 14s | Narrow, file-specific |
| OpenAI broad (gpt-4.1-mini cluster) | 8 | $0.10 | 2m 39s | Core conventions only — agents-level subset |
| OpenAI broad (gpt-4.1 full cluster) | — | — | — | Needs OpenAI tier 2+; tier 1 hits rate limits |
| **Anthropic broad (Haiku 4.5)** | **21** | $0.47 | 8m 17s | **Convention / principle / ADR mix — recommended depth** |
| **Anthropic broad (Haiku 4.5)** | **17** | $0.45 | 4m 55s | **Convention / principle / ADR mix — recommended depth** |

OpenAI broad is positioned as a "no-Anthropic-key" budget alternative — it reliably catches the 6–8 core repo-wide conventions (non-null assertion bans, function-param destructure rules, test-utility imports, CLI version pinning, etc.) at 5× lower cost than Anthropic broad. For full depth (20+ conventions including ADR-worthy decisions) use Anthropic broad.
OpenAI broad is positioned as a "no-Anthropic-key" budget alternative — it reliably catches the 6–8 core repo-wide conventions (non-null assertion bans, function-param destructure rules, test-utility imports, CLI version pinning, etc.) at ~5× lower cost than Anthropic broad. For the same depth of convention / principle / ADR-style candidates, use Anthropic broad.
30 changes: 30 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Examples

Real output and ready-to-use templates for `promote-cli`.

## What's here

| Folder | What it shows |
| --- | --- |
| [`digests/`](./digests/) | Sample markdown digests from real `promote scan` runs against [`trpc/trpc`](https://github.com/trpc/trpc) |
| [`patches/`](./patches/) | Illustrative diffs of what `promote` writes to your memory files |
| [`github-actions/`](./github-actions/) | A weekly scheduled workflow that opens a bundled memory PR |

## Suggested reading order

1. **[`digests/sample-quick.md`](./digests/sample-quick.md)** — what a fast scan ($0.07, 2m) looks like. Three representative candidates from a 24-candidate run.
2. **[`digests/sample-broad.md`](./digests/sample-broad.md)** — what a deeper scan ($0.45, 5m) looks like. Same repo, different mode; surfaces convention-level patterns.
3. **[`patches/claude-rule.patch`](./patches/claude-rule.patch)** and **[`patches/cursor-rule.patch`](./patches/cursor-rule.patch)** — what gets written when you `Promote` a candidate.
4. **[`github-actions/weekly-digest.yml`](./github-actions/weekly-digest.yml)** — drop-in workflow for running the whole flow on a schedule.

## Generating your own

To produce a digest like these against your own repository:

```bash
npm i -g promote-cli
promote init
promote scan --since 60d --mode quick --out my-digest.md # or --mode broad
```

The digest will land at `my-digest.md` (or `docs/promote/digests/{date}.md` if you skip `--out`). It carries the same structure as the samples above — candidates, evidence trails to source PR comments, suggested patches, and a `Filtered out` appendix for clusters the classifier dropped.
Loading
Loading