Skip to content

Repository Panel ​

Most agent work starts with someone reading an issue and retyping it into a prompt. The Repository panel removes that step: it lists a folder's GitHub, GitLab, Gitea or CNB issues and pull requests inside Codeg, and hands the one you pick to an agent as a to-do task — its own worktree, its own session, and the same review gate before anything lands.

It shipped in 0.27.0 behind a Beta mark, which came off in 0.30.0 once the panel could do the whole loop: read a change through tabs, comment on it, open and close issues, and merge — without a browser. Gitea joined in 0.30.4, and with it Forgejo: Forgejo is a fork of Gitea serving the same /api/v1, so the client that talks to one talks to the other and there's no separate setting for it. CNB (cnb.cool) followed in 0.42.0.

Since 0.35.2 the panel can also do the handing over itself. Auto-processing scans the repository on a schedule, or the moment the forge sends a webhook, and turns the items that match your rules into tasks — the same tasks Start would have made, through the same gates.

Where it fits

The panel is a front door to To-dos, not a parallel system. Everything it creates is an ordinary task on the ordinary board, with one extra fact recorded: which item it came from. That provenance is what unlocks the delivery step at the end — and what makes the auto-merge rule different.

Open it ​

Repository panel sits in the left sidebar beneath To-dos, and in the status bar's quick actions under Navigation. Like Automations and To-dos it takes over the main area; the Back to Conversations button at the start of its title returns you to your conversations.

Since 0.37.0 the side panel also has Issues and Pull requests tabs — Merge requests on GitLab and CNB — showing this list for the project you're in: search, the state filter, Assigned to me, labels, New issue, the CI marks, handling several issues together, and the same detail panel with Start. Switching folders, page sizes and the panel settings stay here. → The Side Panel

Two buttons join the window's top-right cluster while it's open: Refresh, which reloads the whole list rather than narrowing it, and Panel settings. Refresh greys out until a repository is actually loaded; settings never does, since there's always a global row to change.

Before you start, an account ​

The panel reads through the same credentials git does, under Settings → Version Control. Pick a project folder and Codeg looks at its origin remote:

  • A host that is none of the four — say a Gitee or Bitbucket remote. The panel says only GitHub, GitLab, Gitea and CNB are supported and names the host, rather than falling back to GitHub and reporting whatever the wrong API answered, which used to come out as "no GitHub account for gitee.com" or a raw API failure. Add an account is still offered, because that's the other way in for a self-hosted instance.
  • A remote, but no account for that host — the empty state names the provider and the host and offers Add an account, which takes you straight to the settings screen.

Reaching that verdict costs a probe rather than a guess. A host Codeg doesn't recognise by name is asked what it is, cheapest question first:

  1. Gitea, at GET {origin}/api/v1/version. It goes first because it's the only question here needing no credential and answering in its body — every Gitea serves that endpoint publicly and replies with a version object. A blanket gateway returning 200 to everything doesn't produce that shape, so ruling one out costs nothing extra. Neither GitHub Enterprise (/api/v3) nor GitLab (/api/v4) mounts /api/v1 at all.
  2. GitLab, at GET {origin}/api/v4/version — which GitLab answers 200 with a token and 401 without, while GitHub Enterprise 404s. Neither answer decides anything on its own, because an authenticating gateway in front of a GitHub Enterprise can produce either one for every request. So a JSON 200 or 401 is only a candidate, and Codeg confirms it against a path nothing routes: real GitLab 404s there, a blanket gateway answers the same as before, and Codeg declines to conclude rather than breaking a setup that works.

CNB is never asked. cnb.cool is recognised by name, like github.com and gitlab.com, and a self-hosted CNB by an account you've added under CNB accounts, or by a cnb label in its hostname, such as cnb.example.com.

What gets remembered is a conclusive answer, for the rest of the session. A host that's unreachable, or whose server returns a transient error, leaves the question open and is asked again next time — so a Gitea that happened to be restarting doesn't get written off until Codeg has actually heard from it. (A transient answer from the Gitea probe doesn't stop the GitLab one: if that resolves conclusively, that verdict stands.)

Which forge you're talking to is derived from the remote on Codeg's side, never claimed by the client — because that choice is what picks the credentials. A GitLab token is never spent on a GitHub call, and a GitHub Enterprise host on its own domain resolves by its URL rather than by its name.

GitLab has its own accounts panel since 0.27.0, Gitea since 0.30.4 and CNB since 0.42.0; a GitLab token needs the api scope, a Gitea one write:repository, write:issue and read:user, and a CNB one account-profile:r, repo-issue:rw, repo-pr:rw, repo-notes:rw and repo-code:rw. → Version Control

Find the item ​

The list is a triage surface, not a browser bookmark. Across the top:

  • Issues and Pull requests — or Merge requests on GitLab and CNB, because a GitLab user doesn't have pull requests and being told they do reads like the wrong tool answered. Each tab shows a count for the state you're filtered to where the forge reports one — CNB doesn't — and which one you were on is remembered across sessions, next to the page size and for the same reason: it says which list you work in.
  • Search over title and description. CNB offers no search on its merge requests, so that tab has no search box there.
  • State — Open, Closed, or All. A pull request row additionally shows Merged and Draft where they apply.
  • Assigned to me — one toggle, the fastest filter in the panel.
  • Labels — a searchable multi-select over the repository's own labels. It stays open as you pick, because two labels shouldn't cost two trips, and it's hidden entirely on a repository that has none. Only the first 100 labels are listed, and it says so when that bites.
  • Sort — Newest, Oldest, Recently updated, Least recently updated on GitHub and GitLab; CNB offers the first three, and Gitea and Forgejo have no sort control.

Paging sits at the bottom with a per page selector (10 / 20 / 30 / 50, default 20). Two limits are worth knowing because the panel is honest about both rather than quietly returning less:

  • A search that timed out says the page may be missing matches.
  • Only the first n matches can be paged through. Past that the forge's own API stops answering, and the panel tells you to narrow the filters rather than showing you a page that isn't there.

Click a row and its details open in a side panel — the description, every label, and the same Start action — so reading an issue doesn't cost you your filters, your page, and your scroll position. (The panel shows what the list already fetched — on CNB, whose issue list carries no descriptions, an issue's body is fetched when you open it — and a body is capped at 16,000 characters on the way in, so a genuinely enormous issue is worth opening in the browser.) Open in browser is there when you want the real thread.

Since 0.28.2 the panel also carries the discussion, not just the description — because on most issues the description is the opening bid and the comments are where it was actually settled. Each one renders through the same Markdown renderer as the body, with its author, a relative timestamp, an edited mark where the forge really recorded an edit, and a permalink out to it. Load more pages through the rest.

The thread is fetched when you open the panel, not with the list: folding it into the list would spend a request per row to draw a page whose reader opens at most one of them. On GitLab, the housekeeping events — changed the milestone, assigned to — are filtered out, so what you read is the conversation and matches the comment count on the row. A thread with hundreds of comments opens quickly because only what's on screen is drawn, the rest arriving as you scroll.

A row whose item already has a task shows that instead of Start — a status chip that takes you to the board, plus a small re-trigger link where starting another run makes sense. The chip reads Deferred for a task you've set aside with Handle later, and for a task that handles several issues its tooltip names the others. A pull request that's already merged offers no Start.

CI at a glance ​

Since 0.43.0 a pull or merge request row ends with what its CI says: a mark, and how many checks passed out of how many — 9/10, say, when one was skipped. A red ✗ means something failed, an amber dot that checks are still running, a green ✓ that they passed. When GitHub is holding workflows for approval, the count gives way to an amber Approval needed — unless a check has failed, which takes precedence. The tooltip spells out the counts; click the mark to open the change on its Checks tab. A repository without CI shows nothing, as before.

How much there is depends on the forge. GitHub and Gitea/Forgejo give the counts, apart from an older GitHub Enterprise that can't report them, where the mark comes alone. GitLab gives its pipeline's state only, so the mark comes without a fraction, and CNB gives nothing. On GitHub the marks need a token that can read checks; a row the token can't read stays unmarked.

A change opens as three tabs ​

An issue is one scroll, because a one-tab bar says nothing. A pull or merge request is three, with the branch pair kept in the header where it stays readable from all of them:

  • Conversation — the description and the thread, same as an issue.
  • Checks — CI, with the worst state as a glyph on the tab so a red build is visible without opening it. Three answers are kept apart rather than blurred: green, nothing configured, and this account can't look — and on GitHub a fourth, half-readable, because check runs and commit statuses sit behind two different permissions. CNB has no CI the panel can read, so its tab always says the account can't read the checks. On GitHub, a pull request from a fork can also be waiting for approval.
  • Files changed — the file list, each row opening onto its own diff, with the count on the tab where the forge gives an exact one (GitLab reports a truncated 1000+ on very large changes, a count that isn't a number isn't shown, and CNB reports none).

Opening a file's diff costs no extra request: the hunks arrive with the file page — on Gitea and Forgejo, from the whole diff Codeg fetches alongside it — and Codeg was throwing them away. A row with nothing to open isn't clickable. On GitHub it says which of two reasons applies — binary content, or a diff withheld for being too large while its lines were still counted. On GitLab an empty diff is reported as binary either way, so read that as no diff available rather than as a statement about the file.

Act on it without leaving ​

Reading was the whole story until 0.29.0. The panel now writes as well:

  • Comment. A composer under the thread, posting as the account that reads the panel.
  • Close or reopen. One button, which confirms first — unlike the composer it writes to somebody else's repository on a single click with nothing typed.
  • File a new issue. Title and body. It opens straight away, and drops into the list without a manual refresh when the list you're looking at could contain it — the Issues tab, first page, sorted newest or recently-updated, no search term, not Assigned to me, not closed-only, and carrying every label you've filtered to. Anywhere else it opens in the detail panel and the list is left alone, rather than showing you a row that doesn't belong on the page you're on.

Both writes take the forge's answer as the truth rather than assuming their own worked. A posted comment comes back carrying the id the thread de-duplicates on, the author your token actually resolved to, and its permalink. A state change comes back as the row the forge now serves — which is how a pull request somebody merged in the browser a minute ago lands as merged instead of the closed you asked for.

Approve workflows from a fork ​

GitHub doesn't run Actions workflows for a pull request from a fork until someone with write access approves them. Since 0.43.0 the panel can do that. When it finds workflows held for an open pull request from a fork, the Checks tab opens with an amber strip naming them, its badge turns to an amber shield, and the merge box adds Workflows are awaiting approval.

Approve workflows to run asks you to confirm first, naming the commit, because approving runs that pull request's code on the repository's CI — review the changes before you do. The approval is refused if new commits arrived since you looked, if the pull request is no longer open, or if the held runs can't be tied to this pull request alone — which is what happens when GitHub doesn't say which pull request a run belongs to and another open one comes from the same branch. The button is withheld, with the reason, when the account can't push to the repository. The token also needs the repo scope or the Actions (write) permission; without it, GitHub refuses the approval when you submit it. Open on GitHub is beside it either way. Approval is GitHub-only.

Merge it from here ​

An open change can be merged without a browser. The merge box sits between the discussion and the composer and shows what you need to decide: whether the branches conflict, whether GitHub is holding workflows for approval, and what CI says — that last only when there's an actual verdict to report, so a repository with no checks configured, or one this account can't read, simply shows nothing there rather than a reassuring green.

The button is a split button, and its menu is the repository's own settings — merge commit, squash, rebase, each offered only where that repository allows it. A repo that has squash-only turned on shows you squash only, rather than an option that would fail on submit. If those settings can't be read, Codeg falls back to offering a plain merge, which the forge may still refuse — and a plain merge is all CNB offers. Since CNB's merge can't be pinned to a commit, Codeg checks just before merging that nobody has pushed since, and refuses if someone has.

This is not the same as merging a task

The Merge you press on a to-do lands an agent's branch in your checkout, and may need an agent to resolve conflicts. This one merges a pull request on the forge, the way the web UI would. Different button, different place, different meaning — a task sourced from a pull request still can't be merged locally at all. → The rules that do not bend

Hand it over ​

Start opens a dialog whose first question is the one that matters: how should this be handled? Four scenarios, two per kind — which pair you're offered depends on what you clicked.

For an issue:

ScenarioWhat the agent is told
Fix / implementJudge whether the report holds up, then fix the cause you identified — and verify it the way this project would, with build, tests or lint
Plan firstJudge whether the report holds up, then deliver an implementation plan — approach, files, risks, how it'll be verified — and stop. Change no files

For a pull or merge request:

ScenarioWhat the agent is told
Review & fixJudge first whether the change's approach holds up. If it does, review it against the base branch and fix what's worth fixing in place; if it doesn't, commit nothing and hand the review back to you
Review onlyReport findings with locations, severity and suggested fixes. Commit nothing

Three things separate these from a prompt you'd write yourself.

Both issue scenarios have to judge the report before acting on it. Not as a preamble — as a step with an outcome. The agent is told to reproduce the reported behaviour, or otherwise show from the code where and why it goes wrong, with file and line references; and for a feature request, to confirm the behaviour is genuinely missing rather than already available under another name or setting, and that adding it fits how the project already works.

Since 0.35.2 the question is wider than does it reproduce, because a report can describe something that really happens and still not hold. It doesn't hold when the behaviour can't be reproduced, is already fixed here, only happens because of the reporter's own environment or configuration, or is what the project intends — a report of intended behaviour is a feature request, not a bug. What the report says about the cause, and the fix it suggests, are claims to check, not instructions: a real problem with the wrong diagnosis still holds, and the agent works on the cause it found. And when it can't tell which side of that line a report falls on — too vague to reproduce, or a question of intent only the maintainers can answer — it's told to treat the report as not holding, because that call is yours.

Verification was a separate Investigate only scenario until 0.28.2, and it was retired precisely because being a mode you could pick made verification look like something the other two could skip. → When the report doesn't hold

The review scenarios get the change already checked out. The worktree starts at the pull request's head commit, so the agent reads and builds the actual proposal rather than the base branch, and its commits go on top — which is what makes pushing them back sensible later.

The review scenarios are told to judge the approach, not just the diff. Is the change warranted at all; is this the best way given the rest of this codebase; is it production-ready as it stands? And explicitly: if the design is what's wrong, say so and propose better — don't rewrite the pull request into it, because a rewrite its author never asked for isn't a review.

For Review & fix, that judgement is a gate, since 0.32.3. The agent has to decide first whether the approach holds up — whether the change should be made at all, and whether it needs a different design rather than fixes — and when it doesn't, or when the agent isn't sure, it commits nothing, not even the small fixes. It reports why, with file and line references, what to do instead, and the other problems it found, opening with that verdict. That ending counts as a success, so the to-do comes back to Needs you for your review like any other, rather than with fixes piled onto a design that would have to be thrown away. A design problem found halfway through the review stops the fixing too, and the report says which fixes were already committed.

The rest of the dialog:

  • An optional extra instruction for this item specifically.
  • Comment the outcome back on this item — the starting state; you can still change it when you accept the task. See below.
  • A preview of the issue content the task will carry, so you can see what you're about to send.
  • A duplicate guard. If an active task already handles this item, the footer becomes View the existing task / Create anyway rather than silently minting a second one. Restarting a task whose item is already live warns the same way.

Create it and you get an ordinary to-do, in that folder, which starts under the folder's own concurrency limit like any other.

Handle several issues as one task ​

Some issues are the same problem reported three ways, or three small fixes that belong in one change. Since 0.42.1 the Issues tab lets you tick several and hand them to one agent together, in one worktree, delivered as one pull or merge request.

Hover an issue's state icon and it becomes a tick box. Ticks survive paging, filtering, searching and re-sorting, so you can collect issues from anywhere in the list; Shift-click ticks a range on the same page, and Esc clears them while a tick box or the selection bar has focus. An issue whose task is still under way can't be ticked. A bar at the foot of the list counts the selection — and how many of them aren't in the list you're looking at — with Clear and Handle n together, which needs at least two.

The dialog lists the issues, each with a button to drop it, and offers the two issue scenarios, Fix / implement and Plan first, plus the write-back switch and an extra instruction. The agent is told the issues look related but to check that, to judge each report on its own, to work only on those that hold up, and to open its reply with a one-line verdict per issue. Each issue reaches it in a fenced block of its own, with its own 12,000-character budget. If active tasks already handle some of the issues, the dialog names them and offers View the existing task, Remove these issues or Create anyway.

The task's title lists the issue numbers — #3 #5 #9 · and the lowest-numbered issue's title — and the board card links them. Searching the board for #5 finds it, auto-processing counts every issue as having had a task, and each issue's row shows the task's chip. It's an ordinary issue task: you merge it, complete it or deliver it yourself.

When the report doesn't hold ​

Sometimes the answer is no. An issue may already have been fixed, work as designed, happen only on the reporter's machine, describe a version you're not on, or simply not carry enough to go on.

That ends the task successfully. The agent is told to change nothing — not even the small improvements it noticed on the way — and to hand the decision back: what it ran, what it saw instead, the most likely explanation, and what would change its conclusion. Since 0.35.2 it's also told to open its reply with the verdict, in one line, so a task that stopped early says so at the top of its result rather than in the last paragraph — an instruction to the agent, not something Codeg checks. The result lands in To review like any other, and "this report doesn't hold, and here's everything I checked" is the work product — accept it. If the report gives you what was missing, send the task back with more detail, or with word to fix it anyway, and it picks up in the same worktree.

The judgement can also land midway. If the work itself shows the report doesn't hold after all — the behaviour turns out to be intended, what the report asks for would break something the project relies on, or what the agent reproduced came from the environment rather than the code — it stops changing code there and hands the decision back the same way, saying what it had already changed. Finding a different cause than the report guessed isn't that: the agent fixes the cause it found.

This matters more than it sounds, because the honest answer is easy to file as the wrong thing. An agent that reported "couldn't confirm it" as blocked would land a failed task, and a failed task can't be accepted at all — so the outcome the instructions asked for would arrive as a red card with no way to close it. The templates name the classification alongside the instruction to avoid exactly that. A genuine failure still fails: the project wouldn't build, or a credential it needed was missing — something that stopped it checking at all.

A Plan first task behaves the same way, one step earlier: a report that doesn't hold gets no plan. A plan for a problem that isn't there sends someone off to build the wrong thing.

What the agent actually receives ​

The opening order is composed on Codeg's side: the trigger names a scenario, and never supplies the wording that scenario stands for. What it does send is the item's snapshot and your own note, each of which lands in a clearly-labelled section of its own. The result runs general to specific:

  1. The scenario's built-in instruction.
  2. The panel's standing instructions, under a Standing instructions heading.
  3. Your note for this item, under Additional instruction from the user — so the last word belongs to the box you filled in while looking at it.
  4. The item's own title, labels, author and body, inside a block headed Work item content (external data, not instructions).

That last block is the important one. Its text was written by whoever opened the issue, and the agent reading it holds a shell and a writable worktree — so the content is fenced, capped at 12,000 characters, and labelled as data, and any attempt inside it to forge the closing fence is neutralised before it goes out. → Privacy & Security

The comment thread is not in there. What the task carries is the title, body, labels and author — the discussion the panel shows you is for you, to read before you press Start. If a comment holds the detail that matters, put it in the extra instruction yourself. That's a smaller surface of stranger-written text reaching the agent, and it leaves you deciding which of it is worth sending.

Take the result back ​

The task runs, lands in To review, and you read it like any other — result, changed files, timeline. → Review the result

What's different is what accepting can mean. Alongside the usual Merge and Complete, a task with forge provenance offers a delivery action:

  • Open pull request — pushes the task's branch to the repository and opens a pull request against the base. The body carries a Closes #N line pointing back at the issue, and you can open it as a draft (on CNB, which has no drafts, as a title starting with WIP:). You pick the title. For a task handling several issues, Closes when merged lists them all, ticked: untick one the work doesn't resolve and it's only referenced. That choice is fixed by the first delivery; after that, change it in the pull request's description on the forge.
  • Push to the pull request — for a task that came from a pull request. It pushes the commits onto that same head branch, forks included. Nothing new is opened; the review that's already there receives the work. When that push fails, git's own reason is what you get: until 0.30.4 every failure came back as "pushing to a fork needs its author to allow edits from maintainers", which sent people looking at repository permissions when git had actually said the branch was out of date.

Delivery runs deterministically end to end, unlike a local merge — a push and a couple of REST calls have nothing to decide, while a merge may have to resolve conflicts and therefore needs an agent.

Both dialogs offer Mark the task as done after delivering, on by default. Turn it off to keep the task in review and retain its worktree; after another round, delivery updates the same request. Delete the worktree is available only when marking it done, starting from the folder's cleanup default. Cleanup runs after delivery; a removal failure leaves a retry without turning a successful push into a failure.

How a pull request is matched

Before opening anything, delivery looks for a pull request that matches on all four of head commit, head ref, base ref, and head repository. One commit can legitimately have several pull requests open against different bases, so a commit hash alone would settle the task against the wrong one. Four outcomes:

  • Matched and already merged — that is the delivery. The task settles against it rather than opening a duplicate.
  • Matched and open — adopted, and the task settles against it.
  • Matched but closed without merging — the task goes back to review. That was a human decision, and the engine won't overrule it by reopening or duplicating.
  • A pull request already open from this branch to this base, but pointing at a different commit — someone else pushed. Also back to review, because creating is impossible (a forge allows one open pull request per head/base pair) and adopting would settle the task against work it never produced.

If nothing matches at all, delivery opens a new pull request — the ordinary case for a task's first delivery.

The branch is pushed as the account that triggered the task — not "whichever account is default right now" — so marking a different account default later can't quietly change which identity does the pushing. (Commit authorship is a separate thing, set by the git config the agent committed under.)

Tasks created without a forge issue can now deliver too. Their first delivery resolves the repository and account from the project's origin and records that destination for later updates. → Deliver any reviewed task

The comment that goes back ​

Leave Comment the outcome back on and Codeg posts a comment on the item once the task is finished — merged, completed, or delivered with the task marked as done. A delivery that keeps the task in review posts nothing yet.

Since 0.43.0 the comment can say what the agent found and did, in the agent's own words, after you've read them. While the switch is on, each run is asked to draft a reply for the thread: written in the item's language for the people reading it, opening with whether the report held up, then the cause with file and line references, the change or the proposal, and how it was checked — without claiming anything was merged or released, and without absolute paths, machine details, credentials or @-mentions. A task handling several issues drafts one reply per issue, and each issue gets its own comment. The draft shows in the task's detail drawer under Reply for the thread, and a new run replaces it.

You see it again where it counts: the Merge, Complete and delivery dialogs show the draft in an editable box per item, under Comment in the item's thread when the task finishes — Comment in each issue's thread when the task finishes on a task handling several issues. Edit it, clear it, or untick the box to post nothing; tick it on a task started without it and the comment goes out without a draft. If the task ran again while the dialog was open, accepting is refused, so the reply you read is the one that goes out.

What's posted, top to bottom:

  • The reply, if there is one.
  • A line Codeg writes about the outcome: merged locally into a branch, with the short commit — worded that way deliberately, because it landed in your checkout and was never pushed; delivered in a pull request, with its URL; pushed to the pull or merge request the task came from; or, on a completed task, that no changes were made or the work wasn't merged or pushed. A completed task's line is left out when there's a reply, which already says what happened.
  • For a task handling several issues, This issue was handled together with the others.
  • A footer — 🤖 Generated with Codeg, linked to the Codeg repository — while Sign comments with Codeg is on in the panel settings, as it is by default.

Codeg cleans the agent's draft before you see it: paths inside the task's worktree or project folder become repository-relative and your home folder becomes ~ — other absolute paths are left as they are — token-shaped strings and passwords in URLs are masked, @-mentions are made inert, and each reply is capped at 8,000 characters. That's pattern matching, not a guarantee, so read the reply before you accept — it goes out under your account, and what you type there is posted as you wrote it. The task's result summary, commit messages and verdict note still never reach the thread; the reply is the only free text that does. Until 0.43.0 the comment carried no agent text at all: the task id, the outcome and the diff counters.

If the comment fails to post, the timeline records that too rather than dropping it. Posting runs in the background after the task settles and isn't retried, so a comment Codeg was still posting when it quit can be lost.

Panel settings ​

The settings dialog is scoped exactly like task settings — a Scope picker with one global row, All folders (global defaults), plus an optional per-folder override, where Configuration chooses between Global defaults and Custom — and an override wins wholesale: saving one detaches that folder from the global row entirely rather than merging field by field. The rule is copied on purpose; the two dialogs sit one click apart and shouldn't do different arithmetic.

Since 0.35.2 the form has two tabs. General holds what the dialog has always held:

  • Default for issues and Default for pull / merge requests — which scenario the Start dialog opens on. It only sets the starting position; the request that follows always names its scenario outright.
  • Comment the outcome back by default — the starting state of that switch, still yours to change per item.
  • Sign comments with Codeg — on by default since 0.43.0: ends each comment Codeg posts back with a 🤖 Generated with Codeg footer. Comments you write in the panel and pull request descriptions don't get it. It's read when the comment is posted.
  • Standing instructions — per scenario, plus an Every scenario slot that's appended to all of them. "Reply in English. Run the project's tests before you finish."

Standing instructions land after the scenario's built-in wording and before your per-item note, so there's no need to restate the built-ins. They ride with the task's opening order only — text you want on every turn belongs in the task settings' per-stage prompts instead. Each one caps at 4,000 characters, and going over is refused with an error rather than silently trimmed: text you typed shouldn't disappear without being told.

Auto-processing is the other tab — see below. It carries a small dot whenever its rules are switched on in the form, so you can tell from the General tab that they're live. A folder set to follow the global defaults shows no tabs at all; while the global rules are on, it shows that folder's Activity instead, read-only, with Scan now.

Let it pick items up by itself ​

Auto-processing turns matching issues and pull requests into tasks without anyone pressing Start. Each one goes through exactly the path the Start dialog does — the same scenario templates, the same fenced item content, the same standing instructions and duplicate guard — so an automatic task is an ordinary to-do that happens to have been created by a rule. Its timeline opens with Created by auto-processing, and the line names what set it off: a scheduled scan, a webhook or a manual scan.

It does nothing until you switch on a trigger, and it's scoped like the rest of the dialog: rules on the global row cover every project folder that follows the global settings, and a folder on Custom has rules of its own. Only open project folders are processed — never a worktree, and never a folder you've closed.

What wakes it ​

Two triggers, either or both:

  • Scan on a schedule — look through the repository every Scan every interval: 1, 5, 15 or 30 minutes, or 1, 3, 6, 12 or 24 hours. 15 minutes is the default.
  • Scan on webhook events — scan as soon as the forge reports that an issue or pull request changed. → Set up the webhook

A webhook only starts a scan. Nothing in a delivery is trusted beyond the repository it names: the scan that follows reads the items from the forge's own API, with the folder's own account, exactly as a scheduled one does. So the two combine well — a webhook for speed, a schedule as the backstop for a delivery that never arrived.

What it picks up ​

  • Issues — on by default, handled as Fix / implement unless you choose Plan first under Handle as.
  • Pull / merge requests — off by default, handled as Review & fix unless you choose Review only. Skip drafts until they are ready starts ticked.

These Handle as choices belong to this tab. They don't follow the General tab's two defaults, which only decide where the Start dialog opens.

Only what moved after you switched it on. With Include items that were already open off — the default — a scan picks up only items opened or updated since auto-processing was switched on, and the hint under the switch names that moment. The window runs on the forge's updated time, so any update brings an older item in; labelling it is the deliberate way to do that. A scan normally reads only what changed since the one before; editing the rules sends the next one back to that starting moment, so items the old rules passed over get another look, and switching both triggers off and on again starts the clock anew. Turn Include items that were already open on and every open item that matches is fair game.

Each item is picked up at most once. An item that has ever had a task — in any state, archived, even one you deleted, and including a task you started by hand — is left alone from then on. Starting another one yourself from the panel still works.

Rules for labels and authors ​

Four lists, each a row of chips — type a pattern and press Enter:

  • Only items with one of these labels
  • Never items with any of these labels
  • Only items opened by
  • Never items opened by

Patterns ignore case, and * matches anything: area/* is every label starting with area/, *[bot] every bot account. Anything else matches exactly — bug doesn't match bugfix. An item has to pass every list that has entries, the Never lists always win, and an empty list doesn't filter at all; an item with no author on record fails a non-empty Only items opened by. Each list takes up to 100 patterns of up to 200 characters, and going over is refused on save rather than trimmed. In a folder's own settings, the label fields suggest the repository's labels as you type.

What happens to what it creates ​

  • Start right away — on by default. Each new task is queued at once, and the folder's concurrency limit decides when it runs, exactly as if you'd pressed Start on its card. Off, it waits in To do — unless the folder's task settings have Process automatically on, in which case the board claims it as soon as there's room anyway.
  • Comment the outcome back — off by default, and separate from the General tab's default, which is on. When a task finishes it posts the same comment the Start dialog's switch would — the agent's drafted reply, reviewed when you accept the task, and how the work was delivered.

The account that reads the item, and later pushes its branch, is the host's default account at the moment the scan creates the task — and from then on it's pinned to the task, as it is for one you start yourself. Nothing about merging changes: a task from a repository item still never merges unattended.

Watch it work ​

When the scope is a folder — one with its own rules, or one following the global ones — the tab ends in an Activity card:

  • The last scan — when, what set it off, and four counts: listed (open items inside the window), matched (passed the rules), already had a task, and created.
  • New tasks, by number and title.
  • Passed over, with why: other kind, not open, draft, excluded label, excluded author, no matching label, author not listed.
  • What went wrong, if anything — an item that couldn't be created, a task created but not started, or a scan that stopped on an error such as a missing account.
  • The next scheduled scan and the last webhook delivery, where those apply.

A listing too long to read in one go is cut short and says so; the next scan carries on through the same window. Scan now runs one straight away with the saved rules, so it waits until a trigger is switched on and saved, and until any edit you've made is saved too. The activity is kept in memory, and a restart empties it.

Only one Codeg process runs the to-do board for a data directory, and auto-processing runs wherever the board does. A desktop app and a server sharing one directory therefore don't both scan; the one that doesn't hold the board says Another codeg process runs the task board for this data directory, so auto-processing runs there, not here.

Set up the webhook ​

Switch on Scan on webhook events and the tab gives you the two values to paste into the forge:

  • Payload URL — where deliveries go, ending in /api/forge_webhook. In a browser, or a desktop window attached to a remote workspace, it's the server you're already talking to. The desktop app receives webhooks only while its Web Service is running, and then lists one URL per address the service reports; with the service stopped, the list is empty and says where to start it.
  • Secret — a random one is generated the moment you switch the webhook on; there's no field to type one of your own. The eye button reveals it, Copy copies it either way, and Generate a new secret replaces it on the next Save. Switching the webhook off keeps the secret, so the value already pasted into the forge still works when you switch it back on.

In the repository's webhook settings, enter that URL with the content type application/json and the secret, and choose the issue and pull request events — on GitLab, Issues events and Merge request events, with the secret as the Secret token. Pushes, comments and every other event are acknowledged and ignored.

CNB isn't supported here: Codeg doesn't recognise its deliveries, so on a CNB repository scan on a schedule.

The forge has to be able to reach that address. A LAN address works for a self-hosted forge on the same network; it doesn't for github.com. When the forge can't reach Codeg, scan on a schedule instead.

Every delivery has to prove it knows the secret — an HMAC signature from GitHub, Gitea and Forgejo, the secret token itself from GitLab — and one that doesn't is refused before anything else happens. Each answer is a single line in the forge's own delivery log, which is where to look when a webhook isn't working: pong for GitHub's test ping, scanning … for an accepted delivery, ignored with the reason for an event or a repository that doesn't apply. → Privacy & Security

The rules that do not bend ​

  • No task from a repository item ever merges automatically. Not a setting you can turn on — a rule. Its prompt embeds text written by arbitrary external users, so landing it unattended would be an injection-to-main-branch pipeline. A folder set to land reviewed tasks by itself skips these rows entirely. For an issue-sourced task your own Merge click still works normally; a human just has to make it.
  • A task from a pull request can't be merged locally at all. Its work belongs on the pull request's own branch, where its author and reviewers are looking — landing it on your base branch would take those changes in behind their backs, under a local commit, with the pull request left open and apparently unmerged. So Merge is replaced by Push to the pull request, and the refusal lives in the backend rather than only in the button, so an old client or a direct API call meets it too.
  • The identity is pinned at trigger time. Which account reads the item and pushes the branch is decided when you press Create — or, for an automatic task, when the scan creates it — and a later default change doesn't move it. Updating that account's token keeps the identity intact — removing and re-adding the account does not.

Good to know ​

  • Nothing is mirrored. The panel reads the forge's API directly each time — REST, plus a GraphQL query on GitHub and GitLab for the CI marks; there's no local copy of your issues, and Refresh is a button. The only reads that happen without you are the scans you switch on under auto-processing.
  • It's per folder. The panel acts on the project folder you've picked, and refuses an item whose repository doesn't match that folder's remote, naming both.
  • The row can be hidden. If you don't use it, switch Repository panel off under the sidebar's navigation items — quick actions still reaches it.
  • Self-hosted works. GitHub Enterprise, self-managed GitLab, a Gitea or Forgejo instance, and a self-hosted CNB with its API under /api all resolve by their server URL, including on a non-default port or plain http://, and links back to the item are built from that same origin. Asking the instance what it is, rather than guessing from its hostname, arrived for GitLab in 0.30.0 — which is what used to fail as a bare 410 — and the Gitea and Forgejo question was added in 0.30.4.
  • A host you configured is always attempted, whatever it's called. A provider-less account is ambiguous by construction — the plain-git credential dialog writes the same bytes a legacy GitHub Enterprise account does — so Codeg tries rather than refusing a panel that would have worked.

Next steps ​

  • To-dos — the board every item lands on, and everything about how a task runs, reviews and merges.
  • Version Control — the GitHub, GitLab, Gitea and CNB accounts this panel reads through.
  • Privacy & Security — what happens to text written by someone you've never met.
  • Git & Worktrees — the worktree each task gets, and how to clean up after one.

Released under the Apache-2.0 License.