Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gitea-claude-agent

Self-hosted AI dev agent for Gitea Actions — mention @moko in any issue and Claude responds, brainstorms requirements, then opens a PR.

Gitea Actions Claude Code MIT License

What it does

You: opens an issue:
     "Add a /now endpoint returning current ISO timestamp. @moko"

   ↓ (Gitea Actions cold-start ~30s)

Bot @moko:  "🤔 thinking..."  ← live status comment

   ↓ (Claude reads the issue + comment history + repo)

Bot @moko:  "Need to confirm 3 things before I write code:
              1. Which framework — FastAPI / Flask / standard lib?
              2. Auth required?
              3. Timezone — UTC or server-local?"

You: "@moko FastAPI, no auth, UTC"

   ↓ (Claude reads the full thread again, this time decides to implement)

Bot @moko:  "Done — added `app/routes/now.py` with a single GET /now endpoint.
              I'll prepare a PR."

   📥 Opened PR: https://gitea.example.com/your-name/your-repo/pulls/42
  • You stay in Gitea — no separate dashboard, no Slack bot, no IDE plugin
  • Multi-turn requirements clarification — Claude asks before writing code when the request is vague (brainstorming-style)
  • Auto PR — implements the change on a fresh branch, pushes, opens PR with the conversation transcript in description
  • Self-hosted, your runner, your tokens — nothing leaves your infrastructure
  • Model choice per call: @moko[opus] / @moko[sonnet] / @moko[haiku]

How it works

┌─────────────┐                                       ┌────────────┐
│  Developer  │ ① @moko in issue/PR comment           │   Gitea    │
└─────────────┘ ─────────────────────────────────────▶└─────┬──────┘
                                                            │ ② webhook
                                                            ▼
                                                  ┌─────────────────┐
                                                  │  act_runner     │
                                                  │ (docker)        │
                                                  └────────┬────────┘
                                                           │ ③ spawn job container
                                                           ▼  (custom image w/ claude pre-installed)
                                   ┌───────────────────────────────────────┐
                                   │  .gitea/workflows/claude.yml          │
                                   │   ↓                                   │
                                   │  scripts/run-claude.sh                │
                                   │   ├ fetch issue + full comment thread │
                                   │   ├ post "thinking..." status comment │
                                   │   ├ exec `claude --print` w/ context  │
                                   │   ├ PATCH status comment → final reply│
                                   │   └ if git diff → branch + push + PR  │
                                   └──────┬────────────────────────────────┘
                                          │ ④ Gitea REST API (as moko bot)
                                          ▼
                                   ┌────────────┐
                                   │  Gitea     │  ⑤ developer sees moko's reply
                                   └────────────┘

Full architecture in docs/01-architecture.md.

Quickstart (rough — for the impatient)

  1. You already have a self-hosted Gitea + at least one act_runner. If not, see docs/deployment.md.

  2. Build the custom runner image (one-time, ~3 min):

    git clone https://github.com/tkpang/gitea-claude-agent.git
    cd gitea-claude-agent
    docker build -t local/gitea-runner-image:latest runner-image/
  3. Configure the runner to use this image (runner-data/.runner labels or config.yaml):

    runner:
      labels:
        - "ubuntu-latest:docker://local/gitea-runner-image:latest"

    Restart act_runner.

  4. Create a Gitea bot user (e.g. moko) + access token with write:repository,write:user,write:issue scopes. Add the user as admin collaborator on each repo you want to enable.

  5. Get a Claude Code long-lived token:

    claude setup-token   # interactive, opens browser
  6. In the target Gitea repo, set two Actions secrets:

    Name Value
    CLAUDE_CODE_OAUTH_TOKEN from claude setup-token (~108 chars sk-ant-oat-...)
    AGENT_GITEA_TOKEN the bot user's Gitea access token
  7. Copy .gitea/workflows/claude.yml and scripts/run-claude.sh into your target repo, push.

  8. Open an issue ending with @moko. Watch Actions tab.

Full step-by-step in docs/deployment.md.

Per-call model selection

Default model is opus. Override per call:

@moko[sonnet] Fix the typo in README
@moko[haiku]  What does this regex do?
@moko[opus]   Refactor the auth module
@moko         (no brackets — uses default)

To change the repo-wide default, uncomment MOKO_MODEL in .gitea/workflows/claude.yml.

Project status

🟡 MVP — works end-to-end on the author's setup. Light on tests. Sharp edges:

  • Cold start ~30s per invocation (Gitea Actions overhead, not Claude)
  • Status comment is a single edit-in-place comment (no GitHub-Checks-style ✅/⏳ — Gitea has no equivalent API)
  • No PR diff line-comments yet (review mode); only issue/PR conversation
  • One workflow run per @moko mention — long brainstorming threads are okay but each round restarts the container

The longer-term plan (docs/02-roadmap.md) is to move to a long-running webhook service (Route B) to eliminate cold start. PRs welcome.

Layout

.
├── .gitea/workflows/claude.yml   The Gitea Actions trigger + steps
├── scripts/run-claude.sh         The actual orchestration (~250 lines bash)
├── runner-image/Dockerfile       Custom job image (Debian + node + git + claude CLI pre-installed)
├── docs/
│   ├── 01-architecture.md
│   ├── 02-roadmap.md             Route A (current) → Route B (long-running webhook)
│   ├── 03-porting-plan.md        Origins: lift-and-shift from anthropics/claude-code-action
│   ├── 04-decisions.md           ADRs
│   └── deployment.md             Step-by-step self-host guide
└── examples/
    ├── docker-compose.yml        Reference: Gitea + Postgres + act_runner
    └── env.example

Why not just use claude-code-action?

anthropics/claude-code-action is GitHub-only — its @octokit/* calls target the GitHub API. This project is a Gitea-native lift-and-shift of the same ergonomics:

Feature claude-code-action (GitHub) gitea-claude-agent (this)
@bot mention triggers
Multi-turn discussion
Auto-implement + PR
Status checklist on PR ✅ (Checks API) 🟡 single edit-in-place comment
Multi-mode (tag/agent/review) only tag mode for now
MCP server integration ⏳ planned
Runs on GitHub Actions Gitea Actions

Acknowledgements

License

MIT — see LICENSE.

About

Self-hosted AI dev agent for Gitea Actions — mention @moko in any issue and Claude responds, brainstorms requirements, then opens a PR.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages