---
title: "GitHub"
---

# GitHub

Work with GitHub pull requests and issues from a CLI session, and run the agent in GitHub Actions with the ready-made action.

The action reference (`<neuralinverse-cli-action>@<version>` below) is provided to your organisation with access; pin it to a release.

## Commands in a session

Four commands work with the GitHub repository behind your checkout's `origin` remote. They use the [GitHub CLI](https://cli.github.com) (`gh`) when it is installed, which handles sign-in, enterprise hosts and SSO, and otherwise `GITHUB_TOKEN` (or `GH_TOKEN`) against `https://api.github.com` (`GITHUB_API_URL` for GitHub Enterprise Server).

Nothing is pushed, posted or created on GitHub without you confirming it first.

| Command | What it does |
|---|---|
| `/pr-comments [number] [--all]` | Finds the open pull request for the current branch (or the one you name), reads its review threads (with their resolution state), review summaries and conversation comments, and attaches the **unresolved** ones to your next message (`--all`: every thread). Then ask, for example, "address these comments" |
| `/autofix-pr [number]` | Collects the unresolved review threads and the failing check runs of the pull request's head commit, with condensed logs of failed GitHub Actions jobs, and asks the agent to fix them on the current branch, run the tests and summarise per thread and per check. The prompt forbids pushing, replying to or resolving threads. You must be on the pull request's branch |
| `/github-setup` | Writes `.github/workflows/neuralinverse.yml` (shown first; an existing file is kept as `.bak`) and offers to store your current provider's key as a repository secret with `gh secret set` (the key goes to `gh` on standard input). The workflow is not committed or pushed for you |
| `/issue [title]` | Asks for a description, has the model draft a title and body from it and the conversation, shows the draft, and creates the issue only after you confirm |

Text that comes from GitHub (review comments, CI logs) is marked as information, not instructions, when it is handed to the model.

Two related commands work with git and `gh` directly: `/commit` has the agent write a commit message and commit (never pushes), and `/pr` has the agent push the branch and open a pull request with `gh`.

### The workflow `/github-setup` writes

- It runs on `issue_comment` and `pull_request_review_comment` events whose comment contains `@neuralinverse`, and only when the commenter is an owner, member or collaborator.
- On a pull request from the same repository, it checks out the pull request branch, runs the agent in `auto-edit` mode with the comment as the task, commits any changes and pushes them to that branch. On issues and on pull requests from forks, it runs in `read-only` mode.
- The agent's answer is posted back as a comment.
- The provider key comes from the repository secret named after the provider's usual variable (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `OPENROUTER_API_KEY`, and so on, or your provider's `apiKeyEnv`), and the model is the one you used when you ran `/github-setup`.

Bedrock and Vertex AI need cloud credentials in the job, for example `aws-actions/configure-aws-credentials` or `google-github-actions/auth` with OIDC; add that step yourself. Providers configured only in your user settings must also be added to the repository's `.neuralinverse/settings.json`.

## The GitHub Action

The CLI's folder in the Neural Inverse IDE repository is a composite action. It installs `@neuralinverse/cli` from npm, runs one non-interactive prompt (`neuralinverse -p --output-format json`), exposes the answer, session id and cost as step outputs, writes a job summary, and fails the step when the run ends in an error, a refusal or the turn limit.

```yaml
- uses: <neuralinverse-cli-action>@<version>
  with:
    prompt: Summarize the changes in this pull request.
  env:
    ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
```

CLI releases are tagged `cli-v<version>`, for example `@cli-v0.1.0`. Pin the action to a release tag or, for the strongest supply-chain guarantee, to a full commit SHA, and pin `version` too when you want reproducible runs. The CLI's own examples use `@main`, which follows the latest development state.

### Inputs

| Input | Default | Description |
|---|---|---|
| `prompt` | required | The task for the agent |
| `model` | auto | `provider/model`, for example `anthropic/claude-sonnet-5-5` or `openai/gpt-5`. When empty, the CLI picks a model from the credentials it finds |
| `mode` | `auto-edit` | `ask`, `auto-edit`, `read-only`, `full-auto`. Anything that would ask is denied in CI |
| `allow` | | Newline-separated allow rules, for example `run_shell(npm test *)`. Blank lines and `#` comments are ignored |
| `deny` | | Newline-separated deny rules |
| `max-turns` | CLI default | Upper bound on model turns |
| `version` | `latest` | npm version or dist-tag of `@neuralinverse/cli` |
| `working-directory` | `.` | Folder the agent works in |
| `output-format` | `json` | `json` or `stream-json`. With `stream-json`, the raw event log is kept in `output-file` |
| `node-version` | `22` | Node.js version used to run the CLI |

### Outputs

| Output | Description |
|---|---|
| `result` | The agent's final answer |
| `session-id` | Id of the session the run created |
| `cost-usd` | Estimated cost in USD; empty when pricing for the model is unknown |
| `is-error` | `true` if the run failed. The step fails too, so use `if: always()` or `failure()` on later steps that read it |
| `output-file` | Path of the raw CLI output on the runner |

### Credentials

The action never reads secrets by itself. Pass provider credentials as environment variables on the step:

| Provider | Variables |
|---|---|
| Anthropic | `ANTHROPIC_API_KEY` |
| OpenAI | `OPENAI_API_KEY` |
| Google Gemini | `GEMINI_API_KEY` |
| OpenRouter, DeepSeek, Groq, Mistral, xAI | `OPENROUTER_API_KEY`, `DEEPSEEK_API_KEY`, `GROQ_API_KEY`, `MISTRAL_API_KEY`, `XAI_API_KEY` |
| Amazon Bedrock | `AWS_REGION` plus credentials, ideally from `aws-actions/configure-aws-credentials` with OIDC |

Project settings in `.neuralinverse/settings.json` (providers, MCP servers, hooks, permission rules) apply as they do locally.

### Example: answer `/agent` comments

Runs when a trusted collaborator comments `/agent <request>` and posts the answer back. The agent is read-only here.

```yaml
name: Agent on comment
on:
  issue_comment:
    types: [created]

permissions:
  contents: read
  issues: write
  pull-requests: write

jobs:
  answer:
    if: >-
      startsWith(github.event.comment.body, '/agent ') &&
      contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Ask the agent
        id: agent
        uses: <neuralinverse-cli-action>@<version>
        with:
          mode: read-only
          max-turns: '20'
          prompt: |
            You are answering a question posted on issue/PR #${{ github.event.issue.number }}
            in ${{ github.repository }}. Investigate the code and reply concisely in Markdown.

            Question:
            ${{ github.event.comment.body }}
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
      - name: Post the answer
        if: always() && steps.agent.outputs.result != ''
        env:
          GH_TOKEN: ${{ github.token }}
          ANSWER: ${{ steps.agent.outputs.result }}
        run: |
          printf '%s\n' "$ANSWER" > answer.md
          gh issue comment "${{ github.event.issue.number }}" --repo "${{ github.repository }}" --body-file answer.md
```

Comment text is untrusted input. Restrict who can trigger the workflow (the `author_association` check above), keep the mode `read-only` or tightly scoped with `allow`, and give the job no secrets beyond the model key.

### Example: fix lint errors on pull requests

The agent may edit files and run only the linter; the workflow commits the result. It is limited to pull requests from the same repository, because workflows triggered by forks do not receive secrets.

```yaml
name: Auto-fix lint
on:
  pull_request:
    types: [opened, synchronize]

permissions:
  contents: write

jobs:
  lint-fix:
    if: github.event.pull_request.head.repo.full_name == github.repository
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.head_ref }}
      - uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: npm
      - run: npm ci
      - name: Check lint
        id: lint
        run: npm run lint
        continue-on-error: true
      - name: Fix with the agent
        if: steps.lint.outcome == 'failure'
        uses: <neuralinverse-cli-action>@<version>
        with:
          mode: auto-edit
          max-turns: '30'
          allow: |
            run_shell(npm run lint)
            run_shell(npm run lint -- *)
            run_shell(npx eslint *)
          prompt: |
            `npm run lint` fails. Fix every reported problem by editing the source files.
            Do not disable rules or add eslint-disable comments. Re-run the linter until it passes.
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
      - name: Commit fixes
        if: steps.lint.outcome == 'failure'
        run: |
          npm run lint
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git commit -am "fix: resolve lint errors" && git push
```

### Use the result in later steps

Pass outputs through `env` rather than interpolating them into scripts, so model-generated text can never run as shell code:

```yaml
- env:
    RESULT: ${{ steps.agent.outputs.result }}
  run: printf '%s\n' "$RESULT" >> "$GITHUB_STEP_SUMMARY"
```

### Without the action

The action is a thin wrapper; any CI system can do the same. See [Non-interactive use and CI](https://neuralinverse.com/docs/cli/automation/#in-ci).
