Drive an installed LaRuche App through its declared actions, never its files.
日本語の概要は準備中です。原文の説明を表示しています。
Create, search, triage and label GitHub issues.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Open an issue somebody can act on, find the ones that already exist, and keep the backlog
from turning into a landfill. gh where it exists, curl where it does not.
Read github-auth first if anything comes back 401 or 404. Run the shell blocks through
shell_exec.
OWNER_REPO=$(git remote get-url origin | sed -E 's|.*github\.com[:/]||; s|\.git$||')
OWNER=${OWNER_REPO%%/*}
REPO=${OWNER_REPO##*/}
AUTH="Authorization: Bearer ${GITHUB_TOKEN}"
${GITHUB_TOKEN} comes from the LaRuche vault. Never echo it. With gh, none of this is
needed, and --repo OWNER/REPO works from any directory.
GET /issues returns pull requests too. In GitHub's data model a pull request IS an
issue with extra fields, so the issues endpoint hands back both. Every count, every
listing and every bulk operation must filter them out:
if "pull_request" not in item: # a real issue
Skip that check and "close all stale issues" closes people's open pull requests. gh issue list filters them for you; the REST API does not.
The most useful thing you can do with an issue tracker is not open a duplicate.
gh issue list --search "login redirect next parameter" --state all
gh issue list --state open --label bug
gh issue list --assignee @me
gh issue view 42
curl -s -H "$AUTH" \
"https://api.github.com/search/issues?q=$(python -c "
import urllib.parse, sys; print(urllib.parse.quote_plus(sys.argv[1]))" \
"login redirect repo:$OWNER/$REPO state:all")" \
| python -c "
import sys, json
for item in json.load(sys.stdin)['items']:
print(f\"#{item['number']} {item['state']:6} {item['title']}\")"
Search --state all, not just open. A closed issue explaining why something was rejected
is the most valuable result you can get, and it is invisible in the default view.
URL-encode the query. A raw # or : in a query string silently truncates it, and the
search then returns confident nonsense.
An issue is read by someone with no context, possibly months later, possibly you. It needs to be reproducible from its own text.
gh issue create --title "Login redirect drops the ?next= parameter" --body "$(cat <<'BODY'
## What happens
Signing in from `/settings?next=/billing` lands on `/dashboard`, not `/billing`.
## Expected
Redirect to the path in `next`, when it is a same-origin relative path.
## Steps
1. sign out
2. open `/settings?next=/billing`
3. sign in with any account
## Environment
v2.4.1, Firefox 128, Windows 11. Also reproduced on Chrome 129.
## Notes
`auth/middleware.py:88` reads `next` before the session is rebuilt, so it reads an
empty session and falls back to the default.
BODY
)" --label bug
The title is the symptom in one line, not "login broken". The steps must start from a state anyone can reach. Version and platform belong in the issue, not in a follow-up question three days later.
Bundled starting points: templates/bug-report.md and templates/feature-request.md.
gh issue edit 42 --add-label "priority:high,bug" --remove-label needs-triage
gh issue edit 42 --add-assignee @me
gh issue comment 42 --body "Root cause is the middleware ordering, fix in progress."
curl -s -X POST -H "$AUTH" \
"https://api.github.com/repos/$OWNER/$REPO/issues/42/labels" \
-d '{"labels": ["priority:high", "bug"]}'
curl -s -X DELETE -H "$AUTH" \
"https://api.github.com/repos/$OWNER/$REPO/issues/42/labels/needs-triage"
curl -s -X POST -H "$AUTH" \
"https://api.github.com/repos/$OWNER/$REPO/issues/42/assignees" \
-d '{"assignees": ["someone"]}'
Use labels the repository already has. Invented ones fragment the taxonomy and nobody filters on them:
gh label list
An assignee must have write access. Assigning someone who does not is silently ignored: the API returns 201 and the issue stays unassigned.
gh issue close 42 --reason completed # or: not planned
gh issue reopen 42
curl -s -X PATCH -H "$AUTH" \
"https://api.github.com/repos/$OWNER/$REPO/issues/42" \
-d '{"state": "closed", "state_reason": "completed"}'
state_reason is completed or not_planned, with an underscore in the API and a space
in the gh flag. Setting state without a reason leaves the issue closed with no
explanation, which reads as abandoned rather than decided.
Say why in a comment before closing. A closed issue with no final comment is the single most common source of the same bug being reported again.
In the pull request body, these close the issue on merge:
Closes #42 Fixes #42 Resolves #42
They only work when the PR targets the DEFAULT branch. Merging into develop with
Closes #42 closes nothing, and everyone assumes it did.
Start a branch from an issue, which names it and links it in one step:
gh issue develop 42 --checkout
gh issue list --label needs-triage --state openneeds-triage on.needs-triage.Bulk edits are irreversible in practice and hit real people's notifications. List what would be touched first, show it to the user, and only then act.
# 1. see what matches, and confirm it is only issues
gh issue list --label wontfix --state open --json number,title
# 2. only after the user agrees
gh issue list --label wontfix --state open --json number --jq '.[].number' \
| xargs -I{} gh issue close {} --reason "not planned"
With curl, filter the pull requests out explicitly:
curl -s -H "$AUTH" \
"https://api.github.com/repos/$OWNER/$REPO/issues?labels=wontfix&state=open&per_page=100" \
| python -c "
import sys, json
for item in json.load(sys.stdin):
if 'pull_request' not in item:
print(item['number'])"
| Action | gh | REST |
|---|---|---|
| List | gh issue list | GET /repos/O/R/issues |
| View | gh issue view N | GET /repos/O/R/issues/N |
| Create | gh issue create | POST /repos/O/R/issues |
| Label | gh issue edit N --add-label x | POST /repos/O/R/issues/N/labels |
| Assign | gh issue edit N --add-assignee u | POST /repos/O/R/issues/N/assignees |
| Comment | gh issue comment N --body "..." | POST /repos/O/R/issues/N/comments |
| Close | gh issue close N | PATCH /repos/O/R/issues/N |
| Search | gh issue list --search "..." | GET /search/issues?q=... |
per_page is 30, the maximum is 100, and
beyond that you must follow the Link header. "There are 30 open issues" is usually
the page size, not the count.--label "a,b" on gh means two labels, but a label containing a comma cannot be
expressed that way at all. Use repeated --add-label flags.#42 is either. Do not
assume from the number alone.404 on an issue that exists in the browser. Either the token lacks repo for a
private repository, or $OWNER/$REPO was parsed from a remote that is not GitHub. Echo
$OWNER_REPO and check it.
422 Validation Failed on create. A label or an assignee that does not exist. The
errors array names the field. Create the label first, or drop it.
The listing is full of pull requests. The pull_request filter is missing. See the top
of this file.
A comment posts with literal \n in it. The body went through shell interpolation.
Use a here-document with gh, or build the JSON with a tool for curl.
Closes #42 did not close the issue. The pull request targeted a non-default branch,
or the keyword was in a comment rather than the PR description. Only the description
counts.
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Drive an installed LaRuche App through its declared actions, never its files.
日本語の概要は準備中です。原文の説明を表示しています。
Find academic papers on arXiv, with citation counts and BibTeX.
日本語の概要は準備中です。原文の説明を表示しています。
Render text or an image as ASCII art for terminal-friendly output.
日本語の概要は準備中です。原文の説明を表示しています。
Track RSS/Atom feeds and blogs via blogwatcher-cli.
日本語の概要は準備中です。原文の説明を表示しています。
Drive a real web browser: navigate, read, find, click, fill, screenshot
日本語の概要は準備中です。原文の説明を表示しています。
Measure a codebase: lines of code, language mix, and symbol lookups.
日本語の概要は準備中です。原文の説明を表示しています。