This text was generated by an LLM (how cgwalters uses LLMs). cgwalters has not reviewed it yet.
A small Rust toolbox, installed as cgwalters-forge-misctool.
cargo install --path crates/misctool
cgwalters-forge-misctool gh-pr-checks OWNER/REPO#123
cgwalters-forge-misctool operator-issue-diff OWNER/REPO#123gh-pr-checks runs gh pr checks once and keeps its output and exit
status (0 passing, 1 failed, 8 pending). Install and authenticate the GitHub CLI
first, or provide GH_TOKEN in the environment. It does not poll, write to
GitHub or manage credentials. --help works without authentication.
operator-issue-diff OWNER/REPO#N reads an issue body's edit history
(GraphQL userContentEdits) through gh api graphql and prints a unified diff
between the last two revisions, with control characters escaped. It exits 0
when they match or there are fewer than two edits (and says so), 1 when the
body changed, and 2 on errors such as a bad reference, a failed query, a
deleted revision or an edit history that does not end at the current body.
Like gh-pr-checks it only reads, using gh's authentication or GH_TOKEN.
cgwalters-forge-misctool acp-tools [--json] [--timeout SECONDS] -- ADAPTER [ARGS...]acp-tools spawns an ACP adapter over stdio, sends initialize and
session/new, and waits (30 seconds by default, at most 600) for its
available_commands_update. It prints the adapter's agentCapabilities and
the offered command names, as plain text or with --json as one JSON object.
It exits 1 on timeout, adapter exit or a JSON-RPC error. It adds no network
access or credentials of its own; the adapter inherits the environment.
review-corpus is opt-in and uses the same authenticated gh CLI, with only
GET requests to github.com. It collects public review feedback on other people's
PRs, not feedback on the selected login's own PRs:
cgwalters-forge-misctool review-corpus collect --login cgwalters --since 2020-11-01 --out review-corpus.jsonl --state review-corpus-state.json
cgwalters-forge-misctool review-corpus stats review-corpus.jsonl--since includes feedback created on or after that UTC date. Discovery searches
both commenter: and reviewed-by: on public PRs, grouped by PR update month
(including old PRs with recent feedback). Windows at the 1,000-result search
cap split recursively down to seconds; an unsplittable or incomplete search
fails instead of advancing the cursor. Every endpoint is paginated. Search
index lag, deleted feedback and inaccessible repositories can limit coverage.
Reviews and comments that are empty or contain only whitespace are omitted.
So are unsubmitted draft reviews and their inline comments visible through the
caller's credentials.
The optional state saves progress for each PR and update window. Rerun with the
same login, date, output and state to resume; completed runs refresh from the cursor
with a one-day overlap for indexing lag. Without state, discovery starts over
and still merges into any existing output. Keep each login's corpus separate.
Keep state and output together, use one writer, and do not edit state manually.
Output is replaced before state advances, so interrupted processes can safely
repeat work. On Unix, synchronizing the file and directory also saves the
replacement to disk before state advances. On other platforms, the replacement
is not guaranteed to survive a power loss.
A crash during file replacement can leave a FILE.tmp; remove that stale file
before resuming. Previously collected records, including deleted comments, are
retained; edited records replace the same kind/ID. Review bodies have no API
update timestamp, so their updated_at falls back to submitted_at.
Bounded checks prevent silent truncation and keep the collector from retrying
indefinitely. Pagination is limited to 100 pages per list endpoint;
rate-limit retries are limited to five per request, with at most one hour per
wait. Primary and secondary limits honor Retry-After (seconds or HTTP date)
and exhausted X-RateLimit-Reset, using the later deadline. Without a deadline,
403/429 responses wait 60 seconds. Longer waits or exhausted retries fail with
the saved cursor intact; resume later. The collector does not refresh in the
background or write to GitHub, and it adds no credential handling.
Rust's Record, Kind and Outcome types in
crates/misctool/src/review_corpus.rs define one JSON object per comment:
| Field | Type / meaning |
|---|---|
schema_version |
integer, currently 1 |
kind |
review-comment, review-body or pr-comment |
repository, pr_number, pr_author |
owner/name string, positive integer, login string |
comment_id, url |
stable numeric GitHub ID and web URL; identity is (kind, comment_id) |
created_at, updated_at |
RFC 3339 UTC timestamps |
path, language, diff_hunk |
strings or null; PR-level feedback has no path/language/hunk |
commit_id, original_commit_id |
commit SHA strings or null, as exposed by GitHub |
body |
feedback text, treated as untrusted data |
outcome |
file-changed-later, no-later-change or unknown |
Language is a small deterministic extension/basename mapping (Rust, C, C++,
Shell, Python, Go, JavaScript, TypeScript, Docs, YAML, TOML, JSON, Dockerfile,
Makefile); unrecognized paths and PR-level feedback use null. stats prints JSON
counts by repository, language (the "null" bucket includes unknown paths), and
creation year, plus the total number of unique records.
Outcomes are evidence, not proof that the author complied. An inline comment
is anchored to its original_commit_id (or commit_id if the original is
unavailable) in the PR's current commit list, so GitHub remapping a comment onto
a later commit does not hide the intervening change. A later commit yields
file-changed-later if its committer time is after the comment and it lists the
same path (or its previous name on rename). With complete history and no such
change, the outcome is no-later-change. Missing anchors (including rebases),
PR-level feedback and incomplete histories yield unknown, unless a later
change is positively observed. The 250-commit PR and 3,000-file commit API caps
are treated as incomplete. Dates can be rewritten and file changes do not have to
address feedback. This is not a thread-resolution or semantic-compliance test.
Offline tests use reduced public API recordings from ostreedev/ostree#2253 (comment 545915657 and reviews 555323914/555595509), plus explicit mutations for edge cases. Live corpus output is not checked into this repository.
Run just check (formatting, Clippy with warnings denied, and tests).
just workflows-check calls the shared actions lint checkout selected by
ACTIONS_PATH; CI obtains that checkout from the same pinned shared action.
Each subcommand lives in its own module and must have help and tests; see
AGENTS.md.
CI uses the shared workflow lint and read-only review policy. The review
workflow loads workflow/review.toml, workflow/review-command.toml and
workflow/review.md from the base branch, never privileged PR code. Real review
submission stays off unless maintainers set AGENT_REAL_REVIEWS=true and
configure the shared wrapper's repository variables. Configure branch rules
to require CI and review approval with stale approvals dismissed; workflow
files alone cannot enable that gate. Setting up the new privileged trigger
may require an owner to bypass the ruleset.
Push a vVERSION tag matching Cargo.toml to build a static
x86_64-unknown-linux-musl binary, attach it to a release, and attest its
provenance. The release job only publishes on tag pushes, not pull requests.
Verify downloads with gh attestation verify BINARY --repo OWNER/REPO.
Licensed under either MIT or Apache-2.0.