{"id":32161876,"url":"https://github.com/mihaigiurgeanu/pr-tools","last_synced_at":"2026-02-25T13:11:09.332Z","repository":{"id":305126020,"uuid":"1021129742","full_name":"mihaigiurgeanu/pr-tools","owner":"mihaigiurgeanu","description":"Decentralized git pull request and code review flows","archived":false,"fork":false,"pushed_at":"2025-08-02T16:41:21.000Z","size":126,"stargazers_count":2,"open_issues_count":18,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-10-21T13:59:30.368Z","etag":null,"topics":["cli","code-review","git","pull-request"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mihaigiurgeanu.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-16T23:56:38.000Z","updated_at":"2025-07-31T09:48:52.000Z","dependencies_parsed_at":"2025-07-18T13:41:39.880Z","dependency_job_id":"e4d1b143-0d32-412a-9bc7-374f95f1e8a0","html_url":"https://github.com/mihaigiurgeanu/pr-tools","commit_stats":null,"previous_names":["mihaigiurgeanu/pr-tools"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mihaigiurgeanu/pr-tools","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mihaigiurgeanu%2Fpr-tools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mihaigiurgeanu%2Fpr-tools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mihaigiurgeanu%2Fpr-tools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mihaigiurgeanu%2Fpr-tools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mihaigiurgeanu","download_url":"https://codeload.github.com/mihaigiurgeanu/pr-tools/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mihaigiurgeanu%2Fpr-tools/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280272340,"owners_count":26302260,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-21T02:00:06.614Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","code-review","git","pull-request"],"created_at":"2025-10-21T13:59:41.899Z","updated_at":"2026-02-25T13:11:09.324Z","avatar_url":"https://github.com/mihaigiurgeanu.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PR Tools\n\nA set of command-line tools for managing descentralized git pull requests and code review workflows. These tools help with creating PR snapshots, sending notifications to Slack, tracking approvals, merging PRs, reviewing changes, and viewing annotated diffs.\n\nPlease read the [motivation](https://copilot.microsoft.com/shares/pages/VKL8KZ8pMhsYY68x7TZsr) for a more in-depth info about the purpose of these tools.\n\n## Features\n\n- **pr-snapshot**: Generate a Markdown snapshot of the PR including commits and diff summary.\n- **pr-send**: Send the PR snapshot to a Slack channel for review.\n- **pr-track**: Track PR approvals, status, and commit history.\n- **pr-merge**: Merge approved PRs with various strategies and update changelog.\n- **pr-review**: Interactive code review tool with comment management.\n- **pr-view**: View annotated diffs with review comments.\n- **pr-fix**: Fix comments received in a review.\n- **pr-init**: Interactively generate configuration file for pr-tools.\n\n## Installation\n\nThis project is built with Haskell and Cabal. To install:\n\n1. Ensure you have [GHC](https://www.haskell.org/ghc/) and [Cabal](https://www.haskell.org/cabal/) installed. Use [GHCup](https://www.haskell.org/ghcup/) for easy installation.\n   - For Windows, you can use the [Haskell Platform](https://www.haskell.org/platform/).\n   - For macOS, you can install GHC and Cabal via Homebrew:\n     ```\n     brew install ghc cabal-install\n     ```\n2. Clone the repository:\n   ```\n   git clone \u003crepository-url\u003e\n   cd pr-tools\n   ```\n3. Build and install the executables:\n   ```\n   cabal update\n   cabal install\n   ```\n\nThis will install the binaries in `~/.cabal/bin` (or equivalent). Add this directory to your PATH if necessary.\n\n## How to upgrade from source\n\nUpdate the source tree and reinstall:\n\n    cd pr-tools\n    git checkout master \u0026\u0026 git pull \u0026\u0026 cabal install --overwrite-policy=always\n\n## Configuration\n\n\n## Slack Configurations\n\nPR Tools supports two Slack integration methods: Incoming Webhooks for simple text messages and Slack API Tokens for advanced features like file attachments. Webhooks are easier to set up and sufficient for basic notifications, while API Tokens enable uploading detailed content as files, improving readability for long messages (e.g., reviews or snapshots). If both are configured, the tool prioritizes API Tokens for commands that benefit from attachments; otherwise, it falls back to webhooks.\n\n### Webhook Configuration\n\nWebhooks allow posting plain text messages to a Slack channel. This is ideal for short notifications but may truncate or clutter long content.\n\nTo obtain a webhook:\n1. Go to [Slack Apps](https://api.slack.com/apps) and create a new app.\n2. Enable \"Incoming Webhooks\" under \"Add features \u0026 functionality\".\n3. Activate webhooks and add one to a channel, copying the generated URL (starts with `https://hooks.slack.com/services/`).\n\nAdd to your `.pr-tools.yaml`:\n```yaml\nslack-webhook: \"https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX\"\n```\n\nIf not set, commands like `pr-send` will fail, and others (e.g., `pr-merge`) will skip notifications.\n\n### Slack API Token Configuration\n\nAPI Tokens enable file attachments, allowing detailed messages (e.g., from `pr-review send`, `pr-fix send`, `pr-send`) to be uploaded as .md files with a short summary message. This requires a bot token with `files:write` scope.\n\nTo obtain a token:\n1. Go to [Slack Apps](https://api.slack.com/apps) and create a new app.\n2. Under \"Add features \u0026 functionality\", select \"Bots\" and create a bot user.\n3. Under \"OAuth \u0026 Permissions\", add the `files:write` scope (and optionally `chat:write` for messages).\n4. Install the app to your workspace, granting permissions.\n5. Copy the \"Bot User OAuth Token\" (starts with `xoxb-`).\n6. Find the channel ID: In Slack, right-click the channel, select \"View channel details\", and copy the ID (starts with `C` or `G`).\n7. Invite the `pr-tools` bot to the channel:\n   ```\n   /invite @pr-tools\n   ```\n\nAdd to your `.pr-tools.yaml`:\n```yaml\nslack-token: \"xoxb-your-bot-token\"\nslack-channel: \"C0123456789\"  # Channel ID\n```\n\n### Base Branch and Slack Configuration\n\nUse `pr-init` or manually create a `.pr-tools.yaml` file in the project root with:\n```yaml\nbase-branch: main  # or your default base branch\nslack-webhook: \"https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX\"  # optional\nslack-token: \"xoxb-your-bot-token\"  # optional for attachments\nslack-channel: \"C0123456789\"  # required if using token\n```\n\n### Recommended .gitignore Entries\n\nTo avoid committing temporary files generated by pr-tools, add the following to your `.gitignore` file:\n\n```\n.pr-drafts/\n.pr-reviews/\n.pr-fixes/\n.pr-state.yaml\n.pr-tools.yaml  # Optional, if you don't want to commit the config\n```\n\n## Usage\n\n### pr-snapshot\n\nGenerate a Markdown snapshot of the PR including commits and diff summary. The snapshot is saved in .pr-drafts/\u003cbranch\u003e.md. If no message is provided, it opens an editor to enter the description.\n\n```\npr-snapshot [BRANCH] [--base-branch BASE] [--message MESSAGE]\n```\n\n- `BRANCH`: The feature branch (default: current branch).\n- `--base-branch BASE`: Override the configured base branch.\n- `--message MESSAGE`, `-m MESSAGE`: Provide the PR description directly without opening an editor.\n\n### pr-send\n\nSend the PR snapshot to a Slack channel for review. Requires slack-webhook configured.\n\n```\npr-send [BRANCH]\n```\n\n- `BRANCH`: The feature branch (default: current branch).\n\n### pr-track\n\nTrack PR approvals and status.\n\nSubcommands:\n\n```\npr-track approve [BRANCH] --by NAME\npr-track status [BRANCH]\npr-track record [BRANCH]\npr-track update [BRANCH]\npr-track list\npr-track rebase --old-commit HASH [--branch BRANCH] [--new-commit HASH]\n```\n\n- `approve [BRANCH] --by NAME`: Approve the PR by the given name. `BRANCH` defaults to current.\n- `status [BRANCH]`: Get the status, approvals, review status, and merge status for the PR. Checks if commits are merged into the base branch, validates approvals against current content, and shows if the current content has been reviewed. `BRANCH` defaults to current.\n- `record [BRANCH]`: Record or update the commit snapshot for the PR. Synonyms: update, u, r, rec. `BRANCH` defaults to current.\n- `list`: List all tracked PRs with status and approval counts.\n- `rebase --old-commit HASH [--branch BRANCH] [--new-commit HASH]`: Transfer approvals after a rebase if the content hasn't changed. `BRANCH` defaults to current, `--new-commit` defaults to current HEAD.\n\n### pr-merge\n\nMerge approved PRs with various strategies and update changelog. Optionally sends notification to Slack.\n\n```\npr-merge [BRANCH] [--strategy {fast-forward|squash|rebase}] [--base-branch BASE]\n```\n\n- `BRANCH`: The feature branch (default: current).\n- `--strategy STRATEGY`: Merge strategy (default: fast-forward).\n- `--base-branch BASE`: Override the configured base branch.\n\n### pr-review\n\nInteractive code review tool with comment management.\n\nSubcommands:\n\n```\npr-review [--all] start [--base-branch BASE]\npr-review [--all] next\npr-review [--all] previous\npr-review [--all] open\npr-review files\npr-review changes\npr-review comment --file FILE --line LINE --text \"COMMENT\"\npr-review resolve --id ID\npr-review end\npr-review list\npr-review send\npr-review comments [--all] [--with-context]\n```\n\n- `start [--base-branch BASE]`: Start or resume a review session. `--base-branch` overrides configured base.\n- `next`: Move to the next file and open in editor for commenting.\n- `previous`: Move to the previous file and open in editor.\n- `open`: Open the current file in editor for commenting.\n- `files`: List files with changes, indicating current.\n- `changes`: Show the git diff.\n- `comment --file FILE --line LINE --text \"COMMENT\"`: Add a comment via CLI.\n- `resolve --id ID`: Mark a comment as resolved.\n- `end`: End the review session and record the content hash of the reviewed commits.\n- `list`: List all review sessions.\n- `send`: Send the review comments to Slack.\n- `comments [--with-context] [--all]`: List comments,By default, shows unresolved comments. Use `--all` for all, or `--resolved` for only resolved. `--with-context` adds surrounding code.\n\n### pr-view\n\nView annotated diff or comments.\n\nSubcommands:\n\n```\npr-view diff [BRANCH] [--base-branch BASE] [--full]\npr-view comments [BRANCH]\n```\n\n- `diff [BRANCH] [--base-branch BASE] [--full]`: Show annotated diff with comments. `--full` shows complete files including unchanged areas. `BRANCH` defaults to current.\n- `comments [BRANCH]`: List all comments with context. `BRANCH` defaults to current.\n- `--base-branch BASE`: Override the configured base branch.\n\n### pr-fix\n\nManage fix sessions for review comments.\n\nSubcommands:\n\n```\npr-fix start\npr-fix comments [--with-context]\npr-fix files\npr-fix open\npr-fix next\npr-fix previous\npr-fix resolve --id ID --status STATUS [--answer \"Explanation\"]\npr-fix end\npr-fix send\n```\n\n- `start`: Start a fix session by pasting review comments into an editor.\n- `comments [--with-context]`: Display comments, optionally with context.\n- `files`: List files with comments, indicating current.\n- `open`: Open current file with comments inserted for editing and updating status/answers.\n- `next`: Move to next file and open.\n- `previous`: Move to previous file and open.\n- `resolve --id ID --status STATUS [--answer \"EXPLANATION\"]`: Update comment status (e.g., solved, not-solved, will-not-solve) and optional answer via CLI.\n- `end`: End the fix session, requires changes to be committed.\n- `send`: Send fix summary to Slack.\n\n### pr-init\n\nInteractively generate or update configuration file (.pr-tools.yaml) for pr-tools, prompting for base-branch, optional slack-webhook, slack-token, slack-channel, and stale-days (with current values as defaults if updating). Also updates .gitignore with recommended entries.\n\n```\npr-init\n```\n\nNo additional flags.\n\n## Sample Workflow\n\n1. **Create a Feature Branch**: Developer creates a branch, makes changes, and commits.\n2. **Generate Snapshot**: Run `pr-snapshot` to create a Markdown description of the PR.\n3. **Send to Slack**: Run `pr-send` to notify the team via Slack.\n4. **Track Approvals**: Team members approve using `pr-track approve \u003cbranch\u003e` or Slack reactions.\n5. **Conduct Review**: Reviewer runs `pr-review start`, navigates files with `next`/`open`, adds comments, then `pr-review send` to send compact review to Slack.\n6. **Fix Comments**: Developer runs `pr-fix start`, pastes the Slack review message, navigates with `pr-fix next`/`open` to edit files and mark comments (solved/not-solved/will-not-solve), adds answers, or use `pr-fix resolve` for CLI updates, then `pr-fix end` to commit changes, and `pr-fix send` to report back via Slack.\n7. **View Annotated Diff**: Anyone can run `pr-view \u003cbranch\u003e` to see changes with comments (use --full for full files or `pr-view comments` for comment list).\n8. **Handle Rebases**: If you need to rebase before merging, run `pr-track rebase --old-commit \u003cold-head\u003e` after rebasing to transfer approvals if content hasn't changed.\n9. **Merge PR**: Once approved, run `pr-merge \u003cbranch\u003e` to merge and update changelog.\n\nThis workflow enables collaborative reviews without committing review files to the repo, using Slack for communication. The approval system now handles rebases intelligently by tracking both commit IDs and content hashes.\n\n## Contributing\n\nContributions are welcome! Please open an issue or submit a pull request.\n\n## License\n\nThis project is licensed under the BSD-3-Clause License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmihaigiurgeanu%2Fpr-tools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmihaigiurgeanu%2Fpr-tools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmihaigiurgeanu%2Fpr-tools/lists"}