Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"source": "./",
"description": "Autonomous GitHub Project board runner: super-board, super-build, super-qa, super-review, super-collect, visual, git-sync, ui-refine-loop. After install, run /super-board onboard to add the guard hooks, .claude/bin scripts and workflows a plugin cannot ship.",
"category": "development",
"homepage": "https://github.com/EricTechPro/super-board"
"homepage": "https://github.com/mnphuc/super-board-gitea"
}
]
}
4 changes: 2 additions & 2 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"author": {
"name": "Eric Tech"
},
"homepage": "https://github.com/EricTechPro/super-board",
"repository": "https://github.com/EricTechPro/super-board",
"homepage": "https://github.com/mnphuc/super-board-gitea",
"repository": "https://github.com/mnphuc/super-board-gitea",
"license": "MIT",
"keywords": [
"github-projects",
Expand Down
31 changes: 20 additions & 11 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ This repo ships eight skills under `skills/`: five you type (`super-board`, `sup
`super-review`). Architecture findings come from `/super-collect architecture`.
Worktree cleanup (`hooks/cleanup-wt.py`) is a hook, not a skill. README skill tables are generated
by `scripts/super-board-readme-sync.py` from SKILL.md frontmatter and `skills/families.json`.
A board runs on **GitHub (default) or Gitea** — the config's `forge` key decides; every forge
rule, mapping and degradation lives in `skills/super-board/references/gitea.md`. Forge dispatch
code: `scripts/super-board-forge.{py,sh}` + `super-board-gitea-{read.py,api.sh}`.

## The cardinal rule

Expand All @@ -20,22 +23,26 @@ The orchestrator MUST NOT:

- Build, test, review, or fix issues itself. All product work is delegated to workflow lane agents (or `claude -p` workers on the legacy backend).
- Patch the dispatcher script or skill files mid-run, even if it sees a problem. Capture the symptom and tell the user; wait for explicit approval.
- Wait on individual workers or relay their work. They write their evidence back to the GitHub issue + PR. The orchestrator's user-facing output is the dispatch confirmation (claude-p) or one short report per wave (workflow), not the run result.
- Hold context for multi-card progress. State lives on the GitHub Project board + the inflight lockfiles, not in the orchestrator's session.
- Wait on individual workers or relay their work. They write their evidence back to the forge issue + PR (GitHub or Gitea). The orchestrator's user-facing output is the dispatch confirmation (claude-p) or one short report per wave (workflow), not the run result.
- Hold context for multi-card progress. State lives on the board (GitHub Project / Gitea project) + the inflight lockfiles, not in the orchestrator's session.

If a problem surfaces during the run, the orchestrator's reply is: "I saw X. Want me to dig in or stop the runner?" — not "I went ahead and fixed it."

## Worker rules

Workers (`super-build`, `super-qa`, `super-review`) share the dispatcher's `gh` token bucket. They MUST:
Workers (`super-build`, `super-qa`, `super-review`) share the dispatcher's forge token bucket
(the `gh` GraphQL+REST budget, or the Gitea instance's API limits — often disabled, in which
case the per-worker call budget is the only guard). They MUST:

- Required GitHub reads use `.claude/bin/super-board-github-read.py`; exit 79 stops the run.
- Check its `--check` before GitHub writes, migrations, merges, and new dispatch; preserve work when halted.
- Source `.claude/bin/super-board-gh-guard.sh` (`scripts/` in this repo) at worker start.
- Call `sb_gh_guard_check 200` before any burst of `gh` calls.
- Prefer local `git blame` / `git log` over `gh api graphql` for any sub-agent that doesn't need fresh state.
- Cap adversarial sub-agents at 50 gh calls each. If a sub-agent runs out, it returns `confidence: insufficient_data` rather than burning the shared quota.
- Append `gh-quota-on-exit: graphql=<n>/5000 rest=<n>/5000` to the PR handoff comment.
- Required reads use the forge's wrapper — `.claude/bin/super-board-github-read.py`, or
`.claude/bin/super-board-gitea-read.py` on gitea boards; exit 79 stops the run.
- Check its `--check` before forge writes, migrations, merges, and new dispatch; preserve work when halted.
- Source `.claude/bin/super-board-gh-guard.sh` (`scripts/` in this repo) at worker start — it is forge-aware.
- Call `sb_gh_guard_check 200` before any burst of forge calls.
- Prefer local `git blame` / `git log` over forge API calls for any sub-agent that doesn't need fresh state.
- Cap adversarial sub-agents at 50 forge calls each. If a sub-agent runs out, it returns `confidence: insufficient_data` rather than burning the shared quota.
- Append `gh-quota-on-exit: graphql=<n>/5000 rest=<n>/5000` (GitHub) or
`gh-quota-on-exit: budget=<n> rate_limits=off|<rem>/<limit>` (Gitea) to the PR handoff comment.

See `skills/super-board/references/rate-limit-etiquette.md` for the full discipline.

Expand All @@ -48,7 +55,7 @@ See `skills/super-board/references/rate-limit-etiquette.md` for the full discipl
├── skills/<all eight>/...
├── hooks/guard-*.py, cleanup-wt.py (wired into settings.json; --no-hooks skips)
├── workflows/super-board-wave.js, ui-refine-loop.js
└── bin/super-board-*.sh (incl. pr-body), super-board-*.py (status, merge-policy, agents-md, settings, setup), super-qa-file-bug.sh, super-review-file-refactor.sh
└── bin/super-board-*.sh (incl. pr-body, forge, gitea-api), super-board-*.py (status, merge-policy, agents-md, settings, setup, forge, gitea-read), super-qa-file-bug.sh, super-review-file-refactor.sh
```

It also refreshes the managed `<!-- super-board:begin … -->` block in the target's AGENTS.md when
Expand All @@ -63,6 +70,8 @@ Columns are always Backlog · Ready · Building · QA · Review · Blocked · Do
per-board `variant`. Labels `qa` · `bug` · `feature` route cards: `qa` skips Building, everything
else (and no label) is built. Change routing in `scripts/super-board-wave-plan.sh`,
`workflows/super-board-wave.js` and `run.md` → "Lanes and label routing" together.
On Gitea the seven columns are repo-project columns (`project.number` = the project's API id);
`super-board-card.sh` normalizes both forges into one `{items,totalCount}` shape.

Skills call the dispatcher scripts as `.claude/bin/<script>`.

Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,18 @@
In your project folder:

```bash
curl -fsSL https://raw.githubusercontent.com/EricTechPro/super-board/main/get.sh | bash
curl -fsSL https://raw.githubusercontent.com/mnphuc/super-board-gitea/main/get.sh | bash
```

Or as a Claude Code plugin:

```
/plugin marketplace add EricTechPro/super-board
/plugin marketplace add mnphuc/super-board-gitea
/plugin install super-board@super-board
```

> [!NOTE]
> The plugin ships the skills only. Run `/super-board:super-board onboard` and its 🔍 Checks step adds the guard hooks, scripts and workflows. Needs Claude Code, `gh`, `jq`, bash 3.2+ and Python 3.9+; the installer checks.
> The plugin ships the skills only. Run `/super-board:super-board onboard` and its 🔍 Checks step adds the guard hooks, scripts and workflows. Needs Claude Code, `gh` (GitHub boards) or `tea` v0.16+ (Gitea boards — `forge: "gitea"`), `jq`, bash 3.2+ and Python 3.9+; the installer checks.

Optional post-run learning can delegate an already installed `calibrate` skill after
verified selected work completes. It applies only to explicitly permitted existing
Expand All @@ -51,7 +51,7 @@ canonical skill files; the package bundles no private skill. See
### 1. Install

```bash
curl -fsSL https://raw.githubusercontent.com/EricTechPro/super-board/main/get.sh | bash
curl -fsSL https://raw.githubusercontent.com/mnphuc/super-board-gitea/main/get.sh | bash
```

### 2. Onboard
Expand All @@ -60,7 +60,7 @@ curl -fsSL https://raw.githubusercontent.com/EricTechPro/super-board/main/get.sh
/super-board onboard
```

Checks · GitHub · Board · Branch · AGENTS.md · Policies · Bug sources · Review. <kbd>Enter</kbd> takes the recommended answer.
Checks · Forge (GitHub or Gitea) · Board · Branch · AGENTS.md · Policies · Bug sources · Review. <kbd>Enter</kbd> takes the recommended answer.

### 3. Run

Expand Down
50 changes: 48 additions & 2 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,51 @@
# Release notes

## v3.2.0 — 2026-10-16

A board can live on **Gitea**, not only GitHub: one config key (`"forge": "gitea"`) and the
whole pipeline — board, lanes, merge gate, collectors, onboard — runs against a Gitea/Forgejo
instance through the `tea` CLI. GitHub stays the default and is untouched.

- ✨ **Forge adapter layer.** `super-board-forge.py/.sh` resolve the forge once (env `SB_FORGE`
→ config `forge`/`forge_host`/`forge_login` → git remote → github) and dispatch reads/writes;
every script keeps its verbs, exit codes (79/73/69/67/64/66) and the one shared halt file.
- ✨ **`super-board-gitea-read.py`** — the bounded, read-only twin of github-read: same CLI,
retries, permanent-error halts and `--kind` shapes, with composite reads that normalize
Gitea REST into the github shapes (items/fields/quota/approval/diff…). Writes go through
`super-board-gitea-api.sh` (`tea api`, every spawn timeout-bounded — a hung tea.exe on
Windows fails instead of blocking a worker).
- ✨ **The board is a Gitea repo project.** The seven columns are project columns;
`project.number` is the project's API id. `card.sh` moves a card in one
`POST …/issues/{gid}/move` with the same cache and stale-id retry; onboard's
`board-rank`/`board-migrate` gained `--forge gitea` (additive columns/labels, Skipped→Done,
idempotent re-runs, snapshot first).
- ✨ **Merge gate on Gitea** squash-merges via `POST pulls/{i}/merge` pinned with
`head_commit_id` (the `--match-head-commit` analog); the lost-response reconciliation and
human-approval flow are unchanged. Approval trust fails closed: owner = admin, listed
collaborators = write, `Closes #N` trailers replace `closingIssuesReferences`.
- ✨ **Onboard asks the forge.** Step 2 becomes 🔑 FORGE: tea install/probe (a binary that
hangs counts as missing), host, token via `tea login add` or `GITEA_TOKEN`+`TEA_HOST`, and a
swagger capability gate on the projects-columns API before anything is written.
- ⚡ **Rate-limit honesty.** Gitea instances without limits report `rate_limits_disabled`;
the guard never sleeps on sentinels and the per-worker budget (exit 73) becomes the primary
protection; the throttle steps `max_workers` down only on real 429 evidence.
- 🧪 **Offline tea stub + suites.** `evals/_stubs/bin/tea` is a stateful offline Gitea
(fixtures → `.git/tea-state.json`, calls/writes logs, rate-limit headers); new suites
`test_forge.py`, `test-forge.sh`, `test_gitea_reads.py`, `test-gitea-api.sh`,
`test-card-gitea.sh`, `test-status-gitea.sh`, `test-setup-gitea.sh`,
`test-gh-guard-gitea.sh`, `test-pr-body-gitea.sh`, `test-deps-gitea.sh` plus gitea cases in
`test-throttle.sh` — all in `run-safety.sh`, no network.
- 🐛 **Windows onboard repairs.** `super-board-setup.py` resolves bash via `shutil.which` (a
broken WSL relay no longer shadows Git bash), and reads/writes child output as UTF-8 —
emoji-heavy install output crashed onboard on cp1252 consoles.
- 📝 **`references/gitea.md`** — the mapping table, a gh↔tea dictionary for every literal
command the skills quote, lane checklist and the accepted degradations (no GraphQL economy,
best-effort assignee claims, no draft-issue cards). Screenshot URLs: Gitea pins with
`/raw/commit/<sha>/` (writing-standard.md first, as always).
- Minimum versions: **tea 0.16.x** (`tea api` required; 1.0 renames commands — pinned
spellings live in gitea-read/gitea-api) and a Gitea new enough to serve the
projects-columns endpoints (onboard refuses older instances with a named fix).

## v3.1.2 — 2026-10-11

`/super-collect` dedupes on the exact fingerprint and says when Sentry or PostHog is down.
Expand Down Expand Up @@ -122,7 +168,7 @@ Source links that work away from a checkout.
runs)" count and the family titles in step.
- ✨ **`/visual render --source-base URL [--source-root DIR]`.** Node sources under the source root
become links to the hosted file (`:12-20` → `#L12-L20`); others show as text. The skill-map
pages are re-rendered against `https://github.com/EricTechPro/super-board/blob/main/`.
pages are re-rendered against `https://github.com/mnphuc/super-board-gitea/blob/main/`.
- 🧪 `test-readme-sync.sh` no longer needs a skills badge, and checks both counts and the family
titles after a sync.

Expand Down Expand Up @@ -214,7 +260,7 @@ per file; failures still name the file. `install.sh` records an older install in
> then without `--dry-run`, and check the columns, labels and card statuses before you run
> onboard on the real board.

1. Install over the old copy: `curl -fsSL https://raw.githubusercontent.com/EricTechPro/super-board/main/get.sh | bash`
1. Install over the old copy: `curl -fsSL https://raw.githubusercontent.com/mnphuc/super-board-gitea/main/get.sh | bash`
(or `./install.sh <project>`). It records the version you came from.
2. Run `/super-board onboard`. Step 1 upgrades with no question and lists it under
"Upgraded for you" (backup in `.claude/super-board/backup/<ts>/`):
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.1.2
3.2.0
2 changes: 1 addition & 1 deletion diagrams/_shared/sitenav.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
<a class="logo" href="../"><svg viewBox="0 0 96 96" aria-hidden="true"><rect x="4" y="4" width="88" height="88" rx="20" fill="#0d1117" stroke="#3d444d" stroke-width="2"/><rect x="14" y="16" width="20" height="64" rx="5" fill="#fff" fill-opacity=".08"/><rect x="38" y="16" width="20" height="64" rx="5" fill="#fff" fill-opacity=".08"/><rect x="62" y="16" width="20" height="64" rx="5" fill="#fff" fill-opacity=".08"/><rect x="17" y="20" width="14" height="10" rx="2.5" fill="#d97757"/><rect x="17" y="33" width="14" height="10" rx="2.5" fill="#d97757" fill-opacity=".55"/><rect x="41" y="20" width="14" height="10" rx="2.5" fill="#58a6ff"/><rect x="65" y="20" width="14" height="10" rx="2.5" fill="#3fb950"/><rect x="65" y="33" width="14" height="10" rx="2.5" fill="#3fb950"/><rect x="65" y="46" width="14" height="10" rx="2.5" fill="#3fb950"/></svg>super-board</a>
<span class="sp"></span>
%%MAPNAV%%
<a class="lk" href="https://github.com/EricTechPro/super-board"><svg class="ni" viewBox="0 0 24 24" aria-hidden="true" fill="currentColor"><path d="M12 2a10 10 0 0 0-3.16 19.49c.5.09.68-.22.68-.48v-1.7c-2.78.6-3.37-1.34-3.37-1.34-.45-1.15-1.11-1.46-1.11-1.46-.91-.62.07-.61.07-.61 1 .07 1.53 1.03 1.53 1.03.89 1.53 2.34 1.09 2.91.83.09-.65.35-1.09.64-1.34-2.22-.25-4.55-1.11-4.55-4.94 0-1.09.39-1.98 1.03-2.68-.1-.25-.45-1.27.1-2.64 0 0 .84-.27 2.75 1.02a9.5 9.5 0 0 1 5 0c1.91-1.29 2.75-1.02 2.75-1.02.55 1.37.2 2.39.1 2.64.64.7 1.03 1.59 1.03 2.68 0 3.84-2.34 4.69-4.57 4.93.36.31.68.92.68 1.86v2.75c0 .27.18.58.69.48A10 10 0 0 0 12 2z"/></svg><span class="nl">GitHub</span></a>
<a class="lk" href="https://github.com/mnphuc/super-board-gitea"><svg class="ni" viewBox="0 0 24 24" aria-hidden="true" fill="currentColor"><path d="M12 2a10 10 0 0 0-3.16 19.49c.5.09.68-.22.68-.48v-1.7c-2.78.6-3.37-1.34-3.37-1.34-.45-1.15-1.11-1.46-1.11-1.46-.91-.62.07-.61.07-.61 1 .07 1.53 1.03 1.53 1.03.89 1.53 2.34 1.09 2.91.83.09-.65.35-1.09.64-1.34-2.22-.25-4.55-1.11-4.55-4.94 0-1.09.39-1.98 1.03-2.68-.1-.25-.45-1.27.1-2.64 0 0 .84-.27 2.75 1.02a9.5 9.5 0 0 1 5 0c1.91-1.29 2.75-1.02 2.75-1.02.55 1.37.2 2.39.1 2.64.64.7 1.03 1.59 1.03 2.68 0 3.84-2.34 4.69-4.57 4.93.36.31.68.92.68 1.86v2.75c0 .27.18.58.69.48A10 10 0 0 0 12 2z"/></svg><span class="nl">GitHub</span></a>
<button class="btn" id="sbtt" type="button" aria-label="Toggle light or dark theme"><svg class="ni" viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg><span class="nl">Theme</span></button>
</div></header>
Loading