|
| 1 | +# AGENTS.md — Issue auto-implement action |
| 2 | + |
| 3 | +For agents making changes to this action. This file summarizes flows, design decisions, and implementation details. |
| 4 | + |
| 5 | +## Flows |
| 6 | + |
| 7 | +### 1. Issue to first PR |
| 8 | + |
| 9 | +- **Triggers:** `issues.labeled` (prefixed trigger label), `issue_comment.created` on a labeled issue when **no PR exists yet**. |
| 10 | +- **Flow:** Normalize event → assess (enough info?) → if `request_info`: post comment, add needs-info label, exit. If `implement`: implement step (push to branch `auto-implement-issue-<N>`) → verify → on fail retry (cap `max_implement_retries`); on pass create PR with "Closes #N", add pr-created label, optional comment. |
| 11 | + |
| 12 | +### 2. Issue comment when PR already exists |
| 13 | + |
| 14 | +- **Trigger:** `issue_comment.created` on an issue that **already has an open PR** for that issue. |
| 15 | +- **Flow:** Post a short reply on the issue directing the user to the PR; exit. No assessment or implement. |
| 16 | + |
| 17 | +### 3. PR review or PR conversation comment → iteration |
| 18 | + |
| 19 | +- **Triggers:** `pull_request_review.submitted`, `pull_request_review_comment.created`, or `issue_comment.created` **on a PR** (when `issue.pull_request` is set) when the PR is from an automation branch or body contains "Closes #N". |
| 20 | +- **Flow:** Resolve issue number from PR (body "Closes #N"/"Fixes #N" or head branch `auto-implement-issue-<N>`) → assess with issue + review/comment content → implement ("address review feedback"), push to same branch → verify → on pass: do **not** create PR; post comment on the PR summarizing the new commit(s). |
| 21 | + |
| 22 | +## Event normalization |
| 23 | + |
| 24 | +From the workflow event payload, derive: |
| 25 | + |
| 26 | +- **Issue number:** For `issues` or `issue_comment`: `event.issue.number`. For `pull_request_review` or `pull_request_review_comment`: parse PR body for "Closes #N" or "Fixes #N", or PR head branch for `auto-implement-issue-<N>`. |
| 27 | +- **PR exists for issue (issue_comment only):** Check whether an open PR exists for that issue (e.g. head branch `auto-implement-issue-<N>` or body "Closes #<N>"). |
| 28 | + |
| 29 | +## Request more info vs comment body from implement |
| 30 | + |
| 31 | +- **Request more info (assess):** The **assess** step decides there is **not enough information** to implement. It returns `action: request_info` and a `comment_body`. The workflow posts that on the issue (or on the PR when the trigger was a PR review/comment), adds the `needs-info` label, and **exits without running implement**. |
| 32 | +- **Comment body from implement (no change or need clarification):** The assess step said **implement**. The **implement** step ran (Claude Code CLI with full repo context). When Claude **chose not to make code changes** — e.g. the feedback is a question, the current approach is preferred, or it needs clarification — it **must** write `.comment_body` with the text to post on the PR (one or two sentences). The workflow posts that on the **PR** (review iteration path). If `.comment_body` is missing, the workflow falls back to a generic message. The implement prompt requires Claude to always write `.comment_body` when making no code changes so reviewers get a useful reply. Use for: (a) no-change scenarios (thank the reviewer, briefly explain), or (b) when more information is requested (e.g. "Could you clarify whether you want X or Y?"). |
| 33 | + |
| 34 | +If a reviewer's comment is ambiguous, assess might still return **implement** (optimistic). Then implement runs; Claude can either make a best-effort change, or write `.comment_body` asking for clarification. That clarification is posted on the PR. |
| 35 | + |
| 36 | +## Assess script |
| 37 | + |
| 38 | +- **Path:** `assess/src/index.ts` (TypeScript), run with `npx tsx src/index.ts` from the assess directory (no build). |
| 39 | +- **Input:** Reads event from `GITHUB_EVENT_PATH`; optional context files from input. |
| 40 | +- **Output:** JSON with `action` (`implement` | `request_info`), `comment_body` (if request_info), `verification_notes` (optional), `review_feedback` (when trigger is PR review or comment on PR — exact text for implement to address). Written to file or GITHUB_OUTPUT. |
| 41 | +- **When triggered by PR review:** Include PR review body and review comments in the payload sent to Claude. Assess also sets `review_feedback` from the review/comment so the implement step receives it. |
| 42 | + |
| 43 | +## Implement script |
| 44 | + |
| 45 | +- **Path:** `assess/src/implement.ts`, run with `npx tsx src/implement.ts` from the assess directory. |
| 46 | +- **Env:** `ISSUE_NUMBER`, `GITHUB_REPOSITORY`, `GITHUB_TOKEN`, `AUTO_IMPLEMENT_ANTHROPIC_API_KEY` (required); `VERIFICATION_NOTES`, `REVIEW_FEEDBACK`, `GITHUB_WORKSPACE`, `CONTEXT_FILES`, `IMPLEMENT_COMMIT_MSG_FILE`, `PREVIOUS_VERIFY_OUTPUT` (optional). |
| 47 | +- **Flow:** Fetches issue title/body from GitHub API, loads context files, then runs **Claude Code CLI** (`claude` on PATH) in the repo root with a prompt; the script passes `AUTO_IMPLEMENT_ANTHROPIC_API_KEY` to the CLI as `ANTHROPIC_API_KEY`. When `REVIEW_FEEDBACK` is set (PR review or comment iteration), the prompt includes a "Review feedback to address (you must implement this)" section so the CLI addresses the reviewer's ask (e.g. add tests). The CLI implements in-repo (Read/Edit/Bash). When Claude makes code changes it writes `.commit_msg`, `.pr_title`, `.pr_body`; when it makes no code changes it writes `.comment_body` (no-change rationale or request for clarification). The script ensures commit/PR meta files exist only when Claude did not write `.comment_body`. When `PREVIOUS_VERIFY_OUTPUT` is set (e.g. after a failed verify run), it is included in the prompt so the CLI can fix the implementation. In CI, the action installs the CLI (`npm install -g @anthropic-ai/claude-code`) before the implement step when the assess outcome is `implement`. |
| 48 | + |
| 49 | +## Implement–verify loop |
| 50 | + |
| 51 | +- **Single step** `implement_verify_loop`: for each attempt from 1 to `max_implement_retries`, run implement (with `PREVIOUS_VERIFY_OUTPUT` from the previous failure, if any), commit and push, then run `verify_commands`. If verify passes, exit success. If it fails, set the verify output as `PREVIOUS_VERIFY_OUTPUT` and retry. After all attempts, fail. When this step succeeds: if trigger was `pull_request_review`, `pull_request_review_comment`, or `issue_comment` on a PR (`issue.pull_request` set), post a comment on the existing PR (no new PR); otherwise create PR. |
| 52 | + |
| 53 | +## Branch and PR |
| 54 | + |
| 55 | +- Branch name: `auto-implement-issue-<issue_number>`. |
| 56 | +- PR title or body must include "Closes #N" (or "Fixes #N") so merging auto-closes the issue. |
| 57 | +- On iteration (PR already exists): do not create a new PR; post a comment on the PR summarizing the new commit(s). |
| 58 | + |
| 59 | +## Restricting who can trigger |
| 60 | + |
| 61 | +The first step enforces one of two gates (exactly one must be configured; no bypass): |
| 62 | + |
| 63 | +1. **Permission check** — If `github_allowed_trigger_min_permission` is set (repo variable `AUTO_IMPLEMENT_ALLOWED_TRIGGER_MIN_PERMISSION`: `triage`, `push`, `maintain`, or `admin`), the action calls the repo collaborator permission API and requires the actor to have at least that permission. Works with the default `GITHUB_TOKEN`. |
| 64 | +2. **Team check** — Otherwise, if `github_allowed_trigger_team` is set (repo variable `AUTO_IMPLEMENT_ALLOWED_TRIGGER_TEAM`, e.g. `org/team`), the action checks `github.actor` against that team; if unset or not a member, fail. Token must have `read:org` (PAT if `GITHUB_TOKEN` lacks it). |
| 65 | + |
| 66 | +If neither variable is set, the step fails. When both are set, the permission check is used and the team value is ignored. |
| 67 | + |
| 68 | +## Labels |
| 69 | + |
| 70 | +All automation labels use `label_prefix` (default `automation`): `{prefix}/auto-implement`, `{prefix}/needs-info`, `{prefix}/pr-created`. Create via API if missing. |
| 71 | + |
| 72 | +## Local development |
| 73 | + |
| 74 | +Scripts load a `.env` file from the action root or cwd (see README **Local runs**). Key env: `AUTO_IMPLEMENT_ANTHROPIC_API_KEY`, `GITHUB_TOKEN`, `GITHUB_REPOSITORY`, `ISSUE_NUMBER` (implement). Copy `.env.example` to `.env` and fill; optional `./scripts/setup-local-env.sh --with-gh` to set `GITHUB_TOKEN` from `gh auth token`. |
| 75 | + |
| 76 | +## Verification |
| 77 | + |
| 78 | +When changing this action or the assess script: |
| 79 | + |
| 80 | +1. **Run the assess unit tests locally** before committing: `cd .github/actions/issue-auto-implement/assess && npm ci && npm test`. Do not rely on CI alone—catch failures locally first, then push. |
| 81 | +2. **CI** runs the same tests in `.github/workflows/issue-auto-implement-test.yml` when you push or open a PR that touches `.github/actions/issue-auto-implement/**`. |
| 82 | +3. **Optional:** Run the assess script with a fixture and `AUTO_IMPLEMENT_ANTHROPIC_API_KEY` for end-to-end assessment behavior. |
| 83 | +4. **Full workflow:** Trigger manually on a test issue (trigger label or comment). Ensure repo secrets/variables are set. Inspect the Actions run and the issue/PR; re-run after changes to the implement or verify loop. |
| 84 | + |
| 85 | +## Next steps (implementation backlog) |
| 86 | + |
| 87 | +Possible future improvements: |
| 88 | + |
| 89 | +1. **Fetch all issue comments** — For `issues` and `issue_comment` events, optionally call the GitHub API to list all comments on the issue and include them in the assessment payload (not only the single comment from the event). |
| 90 | +2. **Optional comment when PR is created** — Input `post_pr_comment` exists; when true, post a short comment on the issue linking to the new PR when one is created. |
| 91 | +3. **Local run with fixture and Claude** — `npm run assess:fixture` exists; optional end-to-end testing with real `AUTO_IMPLEMENT_ANTHROPIC_API_KEY`. |
| 92 | + |
| 93 | +Done: context files in assess, implement step (Claude Code CLI), implement–verify loop with re-implement on failure, PR review iteration (comment on PR, no new PR), comment when retries exhausted, secrets/variables and README docs, local assess script. |
0 commit comments