fix: Replace Codeberg dependency with local Forgejo instance (#611)
- Add setup_forge() to bin/disinto: provisions Forgejo via Docker, creates admin + bot users (dev-bot, review-bot), generates API tokens, creates repo, and pushes code — all automated - Rename env vars: CODEBERG_TOKEN→FORGE_TOKEN, REVIEW_BOT_TOKEN→ FORGE_REVIEW_TOKEN, CODEBERG_REPO→FORGE_REPO, CODEBERG_API→ FORGE_API, CODEBERG_WEB→FORGE_WEB, CODEBERG_BOT_USERNAMES→ FORGE_BOT_USERNAMES (with backwards-compat fallbacks) - Rename API helpers: codeberg_api()→forge_api(), codeberg_api_all() →forge_api_all() (with compat aliases) - Add forge_url field to project TOML; load-project.sh derives FORGE_API/FORGE_WEB from forge_url + repo - Update parse_repo_slug() to accept any host URL, not just codeberg - Forgejo data stored under ~/.disinto/forgejo/ (not in factory repo) - Update all 58 files: agent scripts, formulas, docs, site HTML Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
39d30faf45
commit
a66bd91721
58 changed files with 863 additions and 628 deletions
|
|
@ -42,7 +42,7 @@ Matrix listener routes thread replies to `/tmp/supervisor-escalation-reply`,
|
|||
which `supervisor-run.sh` consumes atomically on each run.
|
||||
|
||||
**Environment variables consumed**:
|
||||
- `CODEBERG_TOKEN`, `CODEBERG_REPO`, `CODEBERG_API`, `PROJECT_NAME`, `PROJECT_REPO_ROOT`
|
||||
- `FORGE_TOKEN`, `FORGE_REPO`, `FORGE_API`, `PROJECT_NAME`, `PROJECT_REPO_ROOT`
|
||||
- `PRIMARY_BRANCH`, `CLAUDE_MODEL` (set to sonnet by supervisor-run.sh)
|
||||
- `WOODPECKER_TOKEN`, `WOODPECKER_SERVER`, `WOODPECKER_DB_PASSWORD`, `WOODPECKER_DB_USER`, `WOODPECKER_DB_HOST`, `WOODPECKER_DB_NAME` — CI database queries
|
||||
- `MATRIX_TOKEN`, `MATRIX_ROOM_ID`, `MATRIX_HOMESERVER` — Matrix notifications + human input
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Supervisor Agent
|
||||
|
||||
You are the supervisor agent for `$CODEBERG_REPO`. You were called because
|
||||
You are the supervisor agent for `$FORGE_REPO`. You were called because
|
||||
`supervisor-poll.sh` detected an issue it couldn't auto-fix.
|
||||
|
||||
## Priority Order
|
||||
|
|
@ -19,7 +19,7 @@ Before acting, read the relevant best-practices file:
|
|||
- Memory issues → `cat ${FACTORY_ROOT}/supervisor/best-practices/memory.md`
|
||||
- Disk issues → `cat ${FACTORY_ROOT}/supervisor/best-practices/disk.md`
|
||||
- CI issues → `cat ${FACTORY_ROOT}/supervisor/best-practices/ci.md`
|
||||
- Codeberg / rate limits → `cat ${FACTORY_ROOT}/supervisor/best-practices/codeberg.md`
|
||||
- forge / rate limits → `cat ${FACTORY_ROOT}/supervisor/best-practices/forge.md`
|
||||
- Dev-agent issues → `cat ${FACTORY_ROOT}/supervisor/best-practices/dev-agent.md`
|
||||
- Review-agent issues → `cat ${FACTORY_ROOT}/supervisor/best-practices/review-agent.md`
|
||||
- Git issues → `cat ${FACTORY_ROOT}/supervisor/best-practices/git.md`
|
||||
|
|
@ -32,10 +32,10 @@ source ${FACTORY_ROOT}/lib/env.sh
|
|||
```
|
||||
|
||||
This gives you:
|
||||
- `codeberg_api GET "/pulls?state=open"` — Codeberg API (uses $CODEBERG_TOKEN)
|
||||
- `forge_api GET "/pulls?state=open"` — forge API (uses $FORGE_TOKEN)
|
||||
- `wpdb -c "SELECT ..."` — Woodpecker Postgres (uses $WOODPECKER_DB_PASSWORD)
|
||||
- `woodpecker_api "/repos/$WOODPECKER_REPO_ID/pipelines"` — Woodpecker REST API (uses $WOODPECKER_TOKEN)
|
||||
- `$REVIEW_BOT_TOKEN` — for posting reviews as the review_bot account
|
||||
- `$FORGE_REVIEW_TOKEN` — for posting reviews as the review_bot account
|
||||
- `$PROJECT_REPO_ROOT` — path to the target project repo
|
||||
- `$PROJECT_NAME` — short project name (for worktree prefixes, container names)
|
||||
- `$PRIMARY_BRANCH` — main branch (master or main)
|
||||
|
|
@ -48,20 +48,20 @@ This gives you:
|
|||
When you see "Circular dependency deadlock: #A -> #B -> #A", the backlog is permanently
|
||||
stuck. Your job: figure out the correct dependency direction and fix the wrong one.
|
||||
|
||||
1. Read both issue bodies: `codeberg_api GET "/issues/A"`, `codeberg_api GET "/issues/B"`
|
||||
1. Read both issue bodies: `forge_api GET "/issues/A"`, `forge_api GET "/issues/B"`
|
||||
2. Read the referenced source files in `$PROJECT_REPO_ROOT` to understand which change
|
||||
actually depends on which
|
||||
3. Edit the issue that has the incorrect dep to remove the `#NNN` reference from its
|
||||
`## Dependencies` section (replace with `- None` if it was the only dep)
|
||||
4. If the correct direction is unclear from code, escalate with both issue summaries
|
||||
|
||||
Use the Codeberg API to edit issue bodies:
|
||||
Use the forge API to edit issue bodies:
|
||||
```bash
|
||||
# Read current body
|
||||
BODY=$(codeberg_api GET "/issues/NNN" | jq -r '.body')
|
||||
BODY=$(forge_api GET "/issues/NNN" | jq -r '.body')
|
||||
# Edit (remove the circular ref, keep other deps)
|
||||
NEW_BODY=$(echo "$BODY" | sed 's/- #XXX/- None/')
|
||||
codeberg_api PATCH "/issues/NNN" -d "$(jq -nc --arg b "$NEW_BODY" '{body:$b}')"
|
||||
forge_api PATCH "/issues/NNN" -d "$(jq -nc --arg b "$NEW_BODY" '{body:$b}')"
|
||||
```
|
||||
|
||||
### Stale dependencies (P3)
|
||||
|
|
|
|||
|
|
@ -26,13 +26,13 @@
|
|||
- Modifying pipeline configs in `.woodpecker/` directory
|
||||
|
||||
## Known Issues
|
||||
- Codeberg rate-limits SSH clones. `git` step fails with exit 128. Retrigger usually works.
|
||||
- forge rate-limits SSH clones. `git` step fails with exit 128. Retrigger usually works.
|
||||
- `log_entries` table grows fast (was 5.6GB once). Truncate periodically.
|
||||
- Example (harb): Running CI + harb stack = 14+ containers on 8GB. Memory pressure is real.
|
||||
- CI images take hours to rebuild. Never run `docker system prune -a`.
|
||||
|
||||
## Lessons Learned
|
||||
- Exit code 128 on git step = Codeberg rate limit, not a code problem. Retrigger.
|
||||
- Exit code 128 on git step = forge rate limit, not a code problem. Retrigger.
|
||||
- Exit code 137 = OOM kill. Check memory, kill stale processes, retrigger.
|
||||
- `node-quality` step fails on eslint/typescript errors — these need code fixes, not CI fixes.
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
- Clean worktree: `cd $PROJECT_REPO_ROOT && git worktree remove /tmp/${PROJECT_NAME}-worktree-<N> --force`
|
||||
- Remove `in-progress` label if agent died without cleanup:
|
||||
```bash
|
||||
codeberg_api DELETE "/issues/<N>/labels/in-progress"
|
||||
forge_api DELETE "/issues/<N>/labels/in-progress"
|
||||
```
|
||||
|
||||
## Dangerous (escalate)
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
**Trust closed state.** If a dependency issue is closed, the code is on the primary branch. Period.
|
||||
|
||||
DO NOT try to find the specific PR that closed an issue. This is over-engineering that causes false negatives:
|
||||
- Codeberg shares issue/PR numbering — no guaranteed relationship
|
||||
- forge shares issue/PR numbering — no guaranteed relationship
|
||||
- PRs don't always mention the issue number in title/body
|
||||
- Searching last N closed PRs misses older merges
|
||||
- The dev-agent closes issues after merging, so closed = merged
|
||||
|
|
@ -52,7 +52,7 @@ The only check needed: `issue.state == "closed"`.
|
|||
The supervisor-poll alert 'status unchanged for Nmin' is a false positive for complex implementation tasks. The status is set to 'claude assessing + implementing' at the START of the `timeout 7200 claude -p ...` call and only updates after Claude finishes. Normal complex tasks (multi-file Solidity changes + forge test) take 45-90 minutes. To distinguish a false positive from a real stuck agent: check that the claude PID is alive (`ps -p <PID>`), consuming CPU (>0%), and has active threads (`pstree -p <PID>`). If the process is alive and using CPU, do NOT restart it — this wastes completed work.
|
||||
|
||||
### False Positive: 'Waiting for CI + Review' Alert
|
||||
The 'status unchanged for Nmin' alert is also a false positive when status is 'waiting for CI + review on PR #N (round R)'. This is an intentional sleep/poll loop — the agent is waiting for CI to pass and then for review-poll to post a review. CI can take 20–40 minutes; review follows. Do NOT restart the agent. Confirm by checking: (1) agent PID is alive, (2) CI commit status via `codeberg_api GET /commits/<sha>/status`, (3) review-poll log shows it will pick up the PR on next cycle.
|
||||
The 'status unchanged for Nmin' alert is also a false positive when status is 'waiting for CI + review on PR #N (round R)'. This is an intentional sleep/poll loop — the agent is waiting for CI to pass and then for review-poll to post a review. CI can take 20–40 minutes; review follows. Do NOT restart the agent. Confirm by checking: (1) agent PID is alive, (2) CI commit status via `forge_api GET /commits/<sha>/status`, (3) review-poll log shows it will pick up the PR on next cycle.
|
||||
|
||||
### False Positive: Shared Status File Causes Giant Age (29M+ min)
|
||||
When the status file `/tmp/dev-agent-status` doesn't exist, `stat -c %Y` fails and the supervisor falls back to epoch 0. The computed age is then `NOW_EPOCH/60 ≈ 29,567,290 min`, which is unmistakably a false positive.
|
||||
|
|
@ -73,7 +73,7 @@ Symptom: agent in awaiting_review with PR CI=failure and push CI=success.
|
|||
Fix: inject with explicit pipeline #623 (the pull_request event pipeline), point to the failing step and the specific duplicate blocks to fix. Use: woodpecker_api /repos/4/pipelines?event=pull_request (or look for event=pull_request in recent pipelines list) to find the correct pipeline number before injecting.
|
||||
|
||||
### Race Condition: Review Posted Before PHASE:awaiting_review Transitions
|
||||
**Symptom:** Dev-agent status unchanged at 'waiting for review on PR #N', no `review-injected-disinto-N` sentinel, but a formal review already exists on Codeberg and `/tmp/disinto-review-output-N.json` was written before the phase file updated.
|
||||
**Symptom:** Dev-agent status unchanged at 'waiting for review on PR #N', no `review-injected-disinto-N` sentinel, but a formal review already exists on forge and `/tmp/disinto-review-output-N.json` was written before the phase file updated.
|
||||
|
||||
**Root cause:** review-pr.sh runs while the dev-agent is still in PHASE:awaiting_ci. inject_review_into_dev_session returns early (phase check fails). On subsequent review-poll cycles, the PR is skipped (formal review already exists for SHA), so inject is never called again.
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ PROJECT_TOML=/home/debian/dark-factory/projects/disinto.toml
|
|||
source /home/debian/dark-factory/lib/load-project.sh "$PROJECT_TOML"
|
||||
PHASE_FILE="/tmp/dev-session-${PROJECT_NAME}-<ISSUE>.phase"
|
||||
PR_NUM=<N>; PR_BRANCH="fix/issue-<ISSUE>"; PR_SHA=$(cat /tmp/dev-session-${PROJECT_NAME}-<ISSUE>.phase | grep SHA | cut -d: -f2 || git -C $PROJECT_REPO_ROOT rev-parse origin/$PR_BRANCH)
|
||||
REVIEW_TEXT=$(curl -sf -H "Authorization: token ${CODEBERG_TOKEN}" "${CODEBERG_API}/issues/${PR_NUM}/comments?limit=50" | jq -r --arg sha "$PR_SHA" '[.[] | select(.body | contains("<!-- reviewed: " + $sha))] | last // empty | .body')
|
||||
REVIEW_TEXT=$(curl -sf -H "Authorization: token ${FORGE_TOKEN}" "${FORGE_API}/issues/${PR_NUM}/comments?limit=50" | jq -r --arg sha "$PR_SHA" '[.[] | select(.body | contains("<!-- reviewed: " + $sha))] | last // empty | .body')
|
||||
INJECT_MSG="Review: REQUEST_CHANGES on PR #${PR_NUM}:\n\n${REVIEW_TEXT}\n\nInstructions:\n1. Address each piece of feedback carefully.\n2. Run lint and tests when done.\n3. Commit your changes and push: git push origin ${PR_BRANCH}\n4. Write: echo PHASE:awaiting_ci > "${PHASE_FILE}"\n5. Stop and wait for the next CI result."
|
||||
INJECT_TMP=$(mktemp); printf '%s' "$INJECT_MSG" > "$INJECT_TMP"
|
||||
tmux load-buffer -b inject "$INJECT_TMP" && tmux paste-buffer -t "dev-${PROJECT_NAME}-<ISSUE>" -b inject && sleep 0.5 && tmux send-keys -t "dev-${PROJECT_NAME}-<ISSUE>" '' Enter
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Codeberg Best Practices
|
||||
# Forge Best Practices
|
||||
|
||||
## Rate Limiting
|
||||
Codeberg rate-limits SSH and HTTPS clones. Symptoms:
|
||||
The forge (Forgejo/Gitea) may rate-limit SSH and HTTPS clones. Symptoms:
|
||||
- Woodpecker `git` step fails with exit code 128
|
||||
- Multiple pipelines fail in quick succession with the same error
|
||||
- Retriggers make it WORSE by adding more clone attempts
|
||||
|
|
@ -26,10 +26,10 @@ cd <worktree> && git commit --allow-empty -m "ci: retrigger" --no-verify && git
|
|||
- One pipeline at a time is ideal on this VPS (resource + rate limit reasons).
|
||||
- If >3 pipelines are pending/running, do NOT create more work.
|
||||
|
||||
## OAuth Tokens
|
||||
- OAuth tokens expire ~2h. If Codeberg is down during refresh, re-login required.
|
||||
- API token is in `~/.netrc` — read via `awk` in env.sh.
|
||||
- Review bot has a separate token ($REVIEW_BOT_TOKEN) for formal reviews.
|
||||
## API Tokens
|
||||
- API token is in `.env` as `FORGE_TOKEN` — loaded via env.sh.
|
||||
- Review bot has a separate token (`$FORGE_REVIEW_TOKEN`) for formal reviews.
|
||||
- With local Forgejo, tokens don't expire. For remote forges, check provider docs.
|
||||
|
||||
## Lessons Learned
|
||||
- Retrigger storm on 2026-03-12: supervisor + dev-agent both retriggered during rate limit, caused 5+ failed pipelines. Added cooldown awareness.
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
## Architecture
|
||||
- `review-poll.sh` (cron */10) → finds open PRs with CI pass + no review → spawns `review-pr.sh`
|
||||
- `review-pr.sh` uses `claude -p` to review the diff, posts structured comment
|
||||
- Uses `review_bot` Codeberg account for formal reviews (separate from main account)
|
||||
- Uses `review_bot` forge account for formal reviews (separate from main account)
|
||||
- Skips WIP/draft PRs (`[WIP]` in title or draft flag)
|
||||
|
||||
## Safe Fixes
|
||||
|
|
@ -27,4 +27,4 @@
|
|||
- Review bot must output JSON — prevents self-narration collapse
|
||||
- DISCUSS verdict should be treated same as REQUEST_CHANGES by dev-agent
|
||||
- Error comments must NOT include `<!-- reviewed: SHA -->` — would falsely mark as reviewed
|
||||
- Review bot uses Codeberg formal reviews API — branch protection requires different user than PR author
|
||||
- Review bot uses forge formal reviews API — branch protection requires different user than PR author
|
||||
|
|
|
|||
|
|
@ -132,16 +132,16 @@ echo ""
|
|||
# ── Open PRs ──────────────────────────────────────────────────────────────
|
||||
|
||||
echo "## Open PRs (${PROJECT_NAME})"
|
||||
_open_prs=$(codeberg_api GET "/pulls?state=open&limit=10" 2>/dev/null || echo "[]")
|
||||
_open_prs=$(forge_api GET "/pulls?state=open&limit=10" 2>/dev/null || echo "[]")
|
||||
echo "$_open_prs" | jq -r '.[] | "#\(.number) [\(.head.ref)] \(.title) — updated \(.updated_at)"' 2>/dev/null || echo "No open PRs or query failed"
|
||||
echo ""
|
||||
|
||||
# ── Backlog + In-Progress ─────────────────────────────────────────────────
|
||||
|
||||
echo "## Issue Status (${PROJECT_NAME})"
|
||||
_backlog_count=$(codeberg_api GET "/issues?state=open&labels=backlog&type=issues&limit=50" 2>/dev/null | jq 'length' 2>/dev/null || echo "?")
|
||||
_in_progress_count=$(codeberg_api GET "/issues?state=open&labels=in-progress&type=issues&limit=50" 2>/dev/null | jq 'length' 2>/dev/null || echo "?")
|
||||
_blocked_count=$(codeberg_api GET "/issues?state=open&labels=blocked&type=issues&limit=50" 2>/dev/null | jq 'length' 2>/dev/null || echo "?")
|
||||
_backlog_count=$(forge_api GET "/issues?state=open&labels=backlog&type=issues&limit=50" 2>/dev/null | jq 'length' 2>/dev/null || echo "?")
|
||||
_in_progress_count=$(forge_api GET "/issues?state=open&labels=in-progress&type=issues&limit=50" 2>/dev/null | jq 'length' 2>/dev/null || echo "?")
|
||||
_blocked_count=$(forge_api GET "/issues?state=open&labels=blocked&type=issues&limit=50" 2>/dev/null | jq 'length' 2>/dev/null || echo "?")
|
||||
echo "Backlog: ${_backlog_count}, In-progress: ${_in_progress_count}, Blocked: ${_blocked_count}"
|
||||
echo ""
|
||||
|
||||
|
|
@ -161,7 +161,7 @@ echo ""
|
|||
# ── Blocked Issues ────────────────────────────────────────────────────────
|
||||
|
||||
echo "## Blocked Issues"
|
||||
_blocked_issues=$(codeberg_api GET "/issues?state=open&labels=blocked&type=issues&limit=50" 2>/dev/null || echo "[]")
|
||||
_blocked_issues=$(forge_api GET "/issues?state=open&labels=blocked&type=issues&limit=50" 2>/dev/null || echo "[]")
|
||||
_blocked_n=$(echo "$_blocked_issues" | jq 'length' 2>/dev/null || echo 0)
|
||||
if [ "${_blocked_n:-0}" -gt 0 ]; then
|
||||
echo "$_blocked_issues" | jq -r '.[] | " #\(.number): \(.title)"' 2>/dev/null || echo " (query failed)"
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@ emit_metric() {
|
|||
printf '%s\n' "$1" >> "$METRICS_FILE"
|
||||
}
|
||||
|
||||
# Count all matching items from a paginated Codeberg API endpoint.
|
||||
# Count all matching items from a paginated forge API endpoint.
|
||||
# Usage: codeberg_count_paginated "/issues?state=open&labels=backlog&type=issues"
|
||||
# Returns total count across all pages (max 20 pages = 1000 items).
|
||||
codeberg_count_paginated() {
|
||||
local endpoint="$1" total=0 page=1 count
|
||||
while true; do
|
||||
count=$(codeberg_api GET "${endpoint}&limit=50&page=${page}" 2>/dev/null | jq 'length' 2>/dev/null || echo 0)
|
||||
count=$(forge_api GET "${endpoint}&limit=50&page=${page}" 2>/dev/null | jq 'length' 2>/dev/null || echo 0)
|
||||
total=$((total + ${count:-0}))
|
||||
[ "${count:-0}" -lt 50 ] && break
|
||||
page=$((page + 1))
|
||||
|
|
@ -244,7 +244,7 @@ mkdir -p "$_RETRY_DIR"
|
|||
# Function: run all per-project checks for the currently loaded project config
|
||||
check_project() {
|
||||
local proj_name="${PROJECT_NAME:-unknown}"
|
||||
flog "── checking project: ${proj_name} (${CODEBERG_REPO}) ──"
|
||||
flog "── checking project: ${proj_name} (${FORGE_REPO}) ──"
|
||||
|
||||
# ===========================================================================
|
||||
# P2: FACTORY STOPPED — CI, dev-agent, git
|
||||
|
|
@ -366,8 +366,8 @@ check_project() {
|
|||
if [ "${CHECK_PIPELINE_STALL:-true}" = "true" ]; then
|
||||
status "P2: ${proj_name}: checking pipeline stall"
|
||||
|
||||
BACKLOG_COUNT=$(codeberg_api GET "/issues?state=open&labels=backlog&type=issues&limit=1" 2>/dev/null | jq -r 'length' 2>/dev/null || echo "0")
|
||||
IN_PROGRESS=$(codeberg_api GET "/issues?state=open&labels=in-progress&type=issues&limit=1" 2>/dev/null | jq -r 'length' 2>/dev/null || echo "0")
|
||||
BACKLOG_COUNT=$(forge_api GET "/issues?state=open&labels=backlog&type=issues&limit=1" 2>/dev/null | jq -r 'length' 2>/dev/null || echo "0")
|
||||
IN_PROGRESS=$(forge_api GET "/issues?state=open&labels=in-progress&type=issues&limit=1" 2>/dev/null | jq -r 'length' 2>/dev/null || echo "0")
|
||||
|
||||
if [ "${BACKLOG_COUNT:-0}" -gt 0 ] && [ "${IN_PROGRESS:-0}" -eq 0 ]; then
|
||||
DEV_LOG="${FACTORY_ROOT}/dev/dev-agent.log"
|
||||
|
|
@ -408,14 +408,14 @@ check_project() {
|
|||
if [ "${CHECK_PRS:-true}" = "true" ]; then
|
||||
status "P3: ${proj_name}: checking PRs"
|
||||
|
||||
OPEN_PRS=$(codeberg_api GET "/pulls?state=open&limit=10" 2>/dev/null | jq -r '.[].number' 2>/dev/null || true)
|
||||
OPEN_PRS=$(forge_api GET "/pulls?state=open&limit=10" 2>/dev/null | jq -r '.[].number' 2>/dev/null || true)
|
||||
for pr in $OPEN_PRS; do
|
||||
PR_JSON=$(codeberg_api GET "/pulls/${pr}" 2>/dev/null || true)
|
||||
PR_JSON=$(forge_api GET "/pulls/${pr}" 2>/dev/null || true)
|
||||
[ -z "$PR_JSON" ] && continue
|
||||
PR_SHA=$(echo "$PR_JSON" | jq -r '.head.sha // ""')
|
||||
[ -z "$PR_SHA" ] && continue
|
||||
|
||||
CI_STATE=$(codeberg_api GET "/commits/${PR_SHA}/status" 2>/dev/null | jq -r '.state // "unknown"' 2>/dev/null || true)
|
||||
CI_STATE=$(forge_api GET "/commits/${PR_SHA}/status" 2>/dev/null | jq -r '.state // "unknown"' 2>/dev/null || true)
|
||||
|
||||
MERGEABLE=$(echo "$PR_JSON" | jq -r '.mergeable // true')
|
||||
if [ "$MERGEABLE" = "false" ] && ci_passed "$CI_STATE"; then
|
||||
|
|
@ -429,7 +429,7 @@ check_project() {
|
|||
[ "$AGE_MIN" -gt 30 ] && p3 "${proj_name}: PR #${pr}: CI=${CI_STATE}, stale ${AGE_MIN}min"
|
||||
fi
|
||||
elif ci_passed "$CI_STATE"; then
|
||||
HAS_REVIEW=$(codeberg_api GET "/issues/${pr}/comments?limit=50" 2>/dev/null | \
|
||||
HAS_REVIEW=$(forge_api GET "/issues/${pr}/comments?limit=50" 2>/dev/null | \
|
||||
jq -r --arg sha "$PR_SHA" '[.[] | select(.body | contains("<!-- reviewed: " + $sha))] | length' 2>/dev/null || echo "0")
|
||||
|
||||
if [ "${HAS_REVIEW:-0}" -eq 0 ]; then
|
||||
|
|
@ -454,7 +454,7 @@ check_project() {
|
|||
# ===========================================================================
|
||||
status "P3: ${proj_name}: checking for circular dependencies"
|
||||
|
||||
BACKLOG_FOR_DEPS=$(codeberg_api GET "/issues?state=open&labels=backlog&type=issues&limit=50" 2>/dev/null || true)
|
||||
BACKLOG_FOR_DEPS=$(forge_api GET "/issues?state=open&labels=backlog&type=issues&limit=50" 2>/dev/null || true)
|
||||
if [ -n "$BACKLOG_FOR_DEPS" ] && [ "$BACKLOG_FOR_DEPS" != "null" ] && [ "$(echo "$BACKLOG_FOR_DEPS" | jq 'length' 2>/dev/null || echo 0)" -gt 0 ]; then
|
||||
|
||||
PARSE_DEPS="${FACTORY_ROOT}/lib/parse-deps.sh"
|
||||
|
|
@ -524,7 +524,7 @@ check_project() {
|
|||
if [ -n "${DEP_CACHE[$dep]+x}" ]; then
|
||||
DEP_INFO="${DEP_CACHE[$dep]}"
|
||||
else
|
||||
DEP_JSON=$(codeberg_api GET "/issues/${dep}" 2>/dev/null || true)
|
||||
DEP_JSON=$(forge_api GET "/issues/${dep}" 2>/dev/null || true)
|
||||
[ -z "$DEP_JSON" ] && continue
|
||||
DEP_STATE=$(echo "$DEP_JSON" | jq -r '.state // "unknown"')
|
||||
DEP_CREATED=$(echo "$DEP_JSON" | jq -r '.created_at // ""')
|
||||
|
|
@ -646,8 +646,8 @@ Instructions:
|
|||
_sess_issue="${_sess#dev-"${proj_name}"-}"
|
||||
[[ "$_sess_issue" =~ ^[0-9]+$ ]] || continue
|
||||
|
||||
# Check Codeberg: is the issue still open?
|
||||
_issue_state=$(codeberg_api GET "/issues/${_sess_issue}" 2>/dev/null \
|
||||
# Check forge: is the issue still open?
|
||||
_issue_state=$(forge_api GET "/issues/${_sess_issue}" 2>/dev/null \
|
||||
| jq -r '.state // "open"' 2>/dev/null || echo "open")
|
||||
|
||||
_should_cleanup=false
|
||||
|
|
@ -671,7 +671,7 @@ Instructions:
|
|||
_has_open_pr=0
|
||||
_pr_page=1
|
||||
while true; do
|
||||
_pr_page_json=$(codeberg_api GET "/pulls?state=open&limit=50&page=${_pr_page}" \
|
||||
_pr_page_json=$(forge_api GET "/pulls?state=open&limit=50&page=${_pr_page}" \
|
||||
2>/dev/null || echo "[]")
|
||||
_pr_page_len=$(printf '%s' "$_pr_page_json" | jq 'length' 2>/dev/null || echo 0)
|
||||
_pr_match=$(printf '%s' "$_pr_page_json" | \
|
||||
|
|
@ -689,7 +689,7 @@ Instructions:
|
|||
_has_closed_pr=0
|
||||
_pr_page=1
|
||||
while true; do
|
||||
_pr_page_json=$(codeberg_api GET "/pulls?state=closed&limit=50&page=${_pr_page}" \
|
||||
_pr_page_json=$(forge_api GET "/pulls?state=closed&limit=50&page=${_pr_page}" \
|
||||
2>/dev/null || echo "[]")
|
||||
_pr_page_len=$(printf '%s' "$_pr_page_json" | jq 'length' 2>/dev/null || echo 0)
|
||||
_pr_match=$(printf '%s' "$_pr_page_json" | \
|
||||
|
|
@ -771,7 +771,7 @@ if [ -d "$PROJECTS_DIR" ]; then
|
|||
[ -f "$project_toml" ] || continue
|
||||
PROJECT_COUNT=$((PROJECT_COUNT + 1))
|
||||
|
||||
# Load project config (overrides CODEBERG_REPO, PROJECT_REPO_ROOT, etc.)
|
||||
# Load project config (overrides FORGE_REPO, PROJECT_REPO_ROOT, etc.)
|
||||
source "${FACTORY_ROOT}/lib/load-project.sh" "$project_toml"
|
||||
|
||||
check_project || flog "check_project failed for ${project_toml} (per-project checks incomplete)"
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ SCRATCH_INSTRUCTION=$(build_scratch_instruction "$SCRATCH_FILE")
|
|||
build_prompt_footer
|
||||
|
||||
# shellcheck disable=SC2034 # consumed by run_formula_and_monitor
|
||||
PROMPT="You are the supervisor agent for ${CODEBERG_REPO}. Work through the formula below. You MUST write PHASE:done to '${PHASE_FILE}' when finished — the orchestrator will time you out if you return to the prompt without signalling.
|
||||
PROMPT="You are the supervisor agent for ${FORGE_REPO}. Work through the formula below. You MUST write PHASE:done to '${PHASE_FILE}' when finished — the orchestrator will time you out if you return to the prompt without signalling.
|
||||
|
||||
You have full shell access and --dangerously-skip-permissions.
|
||||
Fix what you can. Escalate what you cannot. Do NOT ask permission — act first, report after.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue