An open API service indexing awesome lists of open source software.

https://github.com/stephanos/nitpick-cli

Run AI code reviews and chats from your terminal or Mac menu bar.
https://github.com/stephanos/nitpick-cli

agent ai cli code-review developer-tools local-first macos

Last synced: 3 days ago
JSON representation

Run AI code reviews and chats from your terminal or Mac menu bar.

Awesome Lists containing this project

README

          

# nitpick-agent

Reusable agent runtime for Nitpick-style code review workflows.

This project is intended to become:

- a Rust library that Nitpick can import for provider/session/review-agent behavior
- a standalone CLI for using the same agent runtime outside the Nitpick app
- a local host daemon that owns shared activity state for CLI and desktop clients
- a macOS menu bar `.app` with Sparkle update checks

Nitpick should continue to own GitHub sync, dashboard state, app lifecycle, and UI. This crate should stay focused on generic agent concerns: provider execution, session continuity, review prompts, structured review output, and chat.

## Storage Model

Review results, review comments, summaries, chat responses, sessions, and activity metadata are local artifacts first. Local storage is the source of truth; GitHub is an outbound sync destination, not the authoritative store.

By default, the host reads config from:

```text
~/Library/Application Support/dev.nitpick.nitpick-agent/config.toml
```

and stores local source-of-truth data under:

```text
~/Library/Application Support/dev.nitpick.nitpick-agent
```

Override these with `NITPICK_AGENT_CONFIG` and `NITPICK_AGENT_DATA_DIR`.
GitHub PR checkouts are retained under the data directory at `checkouts/` by default, and can be moved with `NITPICK_AGENT_CHECKOUT_DIR`.
When the macOS app starts the host daemon, stdout/stderr are appended to `logs/daemon.log` under the nitpick-agent data directory. By default this is `~/Library/Application Support/dev.nitpick.nitpick-agent/logs/daemon.log`.

The host API listens on `127.0.0.1:19783` by default when started with:

```bash
nitpick-agent-host daemon
```

Override the bind address with `NITPICK_AGENT_HOST_ADDR`.

The CLI reads host status from the same local API:

The CLI command tree is now domain-first. Older flat commands such as `nitpick status`,
`nitpick review-requests`, `nitpick reviews`, `nitpick logs`, and `nitpick resume` have been
replaced by the nested forms below.

```bash
nitpick system status
nitpick review start acme/platform#42
nitpick activity inspect acme/platform#42
nitpick review requests
nitpick review requests --new
nitpick chat start acme/platform#42
nitpick review list
nitpick review list --all
nitpick activity logs activity-1
nitpick activity logs acme/platform#42
nitpick activity logs daemon
nitpick activity resume activity-1
nitpick activity resume acme/platform#42
nitpick review sync activity-1 acme/platform#42
nitpick activity list
nitpick artifact list activity-1
nitpick artifact show artifact-1
nitpick artifact sync artifact-1 github
nitpick artifact sync artifact-1 github-review acme/platform#42
nitpick artifact sync artifact-1 github acme/platform#42
nitpick system sync-pending github
nitpick system cleanup-checkouts
```

The daemon can watch review sources and create local review activities automatically. GitHub is the first source adapter; additional source-code providers should plug into the same review-source API. Processed review heads are stored locally, so a review request is not reviewed again until its head SHA changes.

```toml
[sources.github.discovery]
enabled = true
auto_review = true
interval_seconds = 300
allowlist = ["stephanos/*"] # optional: scope discovery to specific owners/repos
```

The older `[github.discovery]` config shape is still accepted for compatibility.

When `allowlist` contains exact `owner/repo` entries or `owner/*`, nitpick scopes the underlying `gh search prs` queries to those repositories or owners before applying the local allowlist/denylist filters.

`artifact sync ... github` without a target uses the GitHub dry-run destination and records the local artifact as pending sync. Provide a target such as `acme/platform#42` to post through `gh pr comment`; the local artifact is then marked synced with the returned comment URL/text. Use `github-review` with a target to stage one review artifact into a pending GitHub draft review. Use `review sync ` to stage all review artifacts from an activity into one pending GitHub draft review. If a pending draft already exists, nitpick updates the draft summary when safe and refuses to add new inline comments until the existing draft is submitted or cleared manually.

GitHub token permissions:

- **Discovery and duplicate detection:** `Pull requests: read` for listing review requests, reading PR metadata and head SHAs, and checking existing PR reviews.
- **Draft review sync (`github-review`, `review sync`):** `Pull requests: write`.
- **Standalone PR comments (`artifact sync ... github `):** `Issues: write`, because pull request conversation comments use the issues comment API.

For fine-grained PATs and GitHub App tokens, those repository permissions are the practical minimum. For classic PATs, `repo` is the practical minimum for private repositories; `public_repo` is enough for public-only repositories.

Agent execution is handled by external commands. By default `provider = "claude"` runs `claude` and `provider = "codex"` runs `codex`; override the executable path with `command` in the config file. Review commands run from the checked-out PR repository with Nitpick MCP tools available. Agents read the PR description and conversation with `pull_request_context`, `pull_request_conversation_comments`, and `existing_review_comments`, record inline findings with `add_review_comment`, and call `finish_review` when done. Nitpick validates comments before creating local review comment artifacts, including rejecting absolute paths, `..` path escapes, missing files, empty comments, and invalid line numbers.

Review command execution is sandboxed by default with `sandbox = "nono"`, which gives the provider read/write access to the checked-out repository and denies writes elsewhere. Disable this only for debugging:

```toml
[agent]
sandbox = "none"
```

For one-off CLI runs, pass `--no-sandbox` before the command:

```bash
nitpick --no-sandbox review start acme/platform#42
nitpick --no-sandbox chat start acme/platform#42
nitpick --no-sandbox activity resume acme/platform#42
```

`chat start ` opens a new interactive provider session in the cached PR checkout. It does not create or resume a stored provider session. `activity resume ` reopens a previously stored provider session.

PR reviews get stable local provider session IDs; Claude receives them with `--session-id`, while Codex currently keeps the ID in local state only. Stored Claude and Codex sessions can be reopened with `nitpick activity resume ` when the activity has a provider session ID. If the provider reports that the saved session no longer exists, nitpick clears the stale local session ID and reports that the activity is no longer resumable. GitHub posting uses `gh` by default; override it with `github_command`.

## Layout

```text
crates/nitpick-agent-core generic review/chat runtime
crates/nitpick-agent-cli terminal entry point
crates/nitpick-agent-client Rust client for the local host API
crates/nitpick-agent-host local daemon process
crates/nitpick-agent-github GitHub adapter helpers
crates/nitpick-agent-integration-tests
host-level integration tests with stubs
macos/ Swift menu bar app and Sparkle packaging
```

## Current Status

This is a scaffold. The core runtime now has the first activity/session/store boundary, command-based provider execution, local JSON-backed artifact storage, schema-versioned store metadata, GitHub review-request discovery, GitHub posting via `gh`, and a host API for status, activities, artifacts, asynchronous review submission, and asynchronous chat submission. The macOS app shell can build with Sparkle.

## Commands

```bash
mise run setup
mise run test
mise run test-macos
mise run build
mise run macos-app
mise run macos-appcast
mise run install
mise run verify
mise exec -- cargo run -p nitpick-agent-cli --bin nitpick -- --help
```

`mise run macos-app` writes `target/macos/Nitpick Agent.app`. `mise run macos-appcast` signs a Sparkle appcast with the private EdDSA key from Keychain account `nitpick-agent` locally. In GitHub Actions, the release workflow reads the private key from the repository secret `SPARKLE_PRIVATE_ED_KEY`.

`mise run install` installs `Nitpick Agent.app` into `/Applications` and launches it. When the app starts, it installs the bundled CLI as `~/.local/bin/nitpick`.

## GitHub CI

The repository has two GitHub Actions workflows:

- `test`: runs `mise run verify` on pushes and pull requests.
- `release`: runs on `v*` tags, builds the signed app archive, generates the Sparkle appcast, and creates a GitHub release.

Release signing expects these GitHub secrets:

- `CODESIGN_IDENTITY`: signing identity passed to `codesign`.
- `SPARKLE_PRIVATE_ED_KEY`: private Sparkle EdDSA key stored as a GitHub repository secret for appcast signing.