fork-manager

ClawSkills 作者 clawskills

Manage forks with open PRs - sync upstream, rebase branches, track PR status, and maintain production branches with pending contributions. Supports automatic conflict resolution via --auto-resolve flag (spawns AI subagents to resolve rebase conflicts). Use when syncing forks, rebasing PR branches, building production branches that combine all open PRs, reviewing closed/rejected PRs, or managing local patches kept outside upstream. Requires Git and GitHub CLI (gh).

安装 / 下载方式

TotalClaw CLI推荐
totalclaw install clawskills:clawskills~glucksberg-fork-manager
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/clawskills%3Aclawskills~glucksberg-fork-manager/file -o glucksberg-fork-manager.md
# Fork Manager Skill

Manage forks where you contribute PRs but also use improvements before they're merged upstream. Includes support for local patches — fixes kept in the production branch even when the upstream PR was closed/rejected.

## When to use

- Sync a fork with upstream
- Check status of open PRs
- Rebase PR branches onto latest upstream
- Build a production branch combining all open PRs + local patches
- Review recently closed/rejected PRs and decide whether to keep locally
- Manage local patches (fixes not submitted or rejected upstream)

## When NOT to use

- General GitHub queries (issues, PRs, CI status on any repo) → use `github` skill instead
- Triaging/ranking/prioritizing issues → use `issue-prioritizer` skill instead
- Reviewing code changes before publishing a PR → use `pr-review` skill instead
- Creating new PRs from scratch (not fork sync) → use `gh pr create` directly

## Execution Model — Orchestrator + Worker

**A skill NUNCA deve ser executada inline pelo agente principal.** Sempre usar o padrão orchestrator/worker:

### Fluxo

1. **Orchestrator (agente principal)** — prepara o contexto e spawna um subagente:
   ```
   sessions_spawn(
     task: "<prompt completo com contexto do repo, config, último history>",
     model: "<model adequado>",
     mode: "run"
   )
   ```
2. **Worker (subagente)** — executa o full-sync/status/rebase/etc. Lê a SKILL.md, segue o fluxo, escreve history.
3. **Monitoramento** — o orchestrator checa progresso a cada **4 minutos** via `sessions_list` / `sessions_history`:
   - Se o worker estiver ativo e progredindo → aguarda
   - Se o worker estiver parado/travado (sem output novo por 2 checks consecutivos) → `subagents kill` + spawna novo worker
   - Se o worker completou → lê o resultado e reporta ao usuário
4. **Fallback** — se o worker falhar (crash, timeout, erro):
   - Orchestrator verifica o estado do repo (`git status`, último checkpoint)
   - Spawna novo worker com contexto atualizado incluindo o ponto onde parou
   - Máximo de **2 retries** antes de reportar falha ao usuário

### Contexto para o Worker

O orchestrator deve incluir no prompt do worker:

- Path da SKILL.md (para o worker ler e seguir)
- Config do repo (inline ou path)
- Última entrada do history (resumo ou path)
- Modo de execução (full-sync, status, rebase-all, etc.)
- Se é cron mode ou manual
- Quaisquer instruções específicas do usuário

### Por que subagente?

- **Resiliência:** se o worker falha, o orchestrator pode recuperar
- **Context window:** a skill é pesada (145+ PRs = muito output). O worker gasta seu context sem poluir o agente principal
- **Paralelismo futuro:** permite spawnar workers para repos diferentes simultaneamente

## Cron Mode

When invoked by a cron job (automated recurring sync), follow these guidelines for efficient execution:

1. **Skip interactive prompts** — auto-resolve decisions that don't require human input:
   - Rebases: attempt automatically, report failures
   - Closed PRs: report but defer decision (don't drop or keep without human input)
   - Audit findings: report but don't act
2. **Compact output** — use the summary format, not full verbose report:
   ```
   🍴 Fork Sync Complete — <repo>
   Main: synced N commits (old_sha → new_sha)
   PRs: X open, Y changed state
   - Rebased: A/B clean (C conflicts)
   Production: rebuilt clean | N conflicts
   Notable upstream: [1-3 bullet highlights]
   ```
3. **Checkpoint on failure** — if a rebase fails or production build has conflicts, write state to `repos/<name>/checkpoint.json` so the next run (or manual invocation) can resume
4. **Time budget** — target <10 minutes total. If rebasing 20+ PRs, batch push at the end instead of per-branch

## Configuration

Configs are organized per repository in `repos/<repo-name>/config.json` relative to the skill directory:

```
fork-manager/
├── SKILL.md
└── repos/
    ├── project-a/
    │   └── config.json
    └── project-b/
        └── config.json
```

Formato do `config.json`:

```json
{
  "repo": "owner/repo",
  "fork": "your-user/repo",
  "localPath": "/path/to/local/clone",
  "mainBranch": "main",
  "productionBranch": "main-with-all-prs",
  "upstreamRemote": "upstream",
  "forkRemote": "origin",
  "autoResolveConflicts": false,
  "openPRs": [123, 456],
  "prBranches": {
    "123": "fix/issue-123",
    "456": "feat/feature-456"
  },
  "localPatches": {
    "local/my-custom-fix": {
      "description": "Breve descrição do que o patch faz",
      "originalPR": 789,
      "closedReason": "rejected|superseded|duplicate|wontfix",
      "keepReason": "Motivo pelo qual mantemos localmente",
      "addedAt": "2026-02-07T00:00:00Z",
      "reviewDate": "2026-03-07T00:00:00Z"
    }
  },
  "lastSync": "2026-01-28T12:00:00Z",
  "notes": {
    "mergedUpstream": {},
    "closedWithoutMerge": {},
    "droppedPatches": {}
  }
}
```

### Resolução automática de conflitos (`autoResolveConflicts`)

A resolução automática pode ser ativada de **duas formas** (qualquer uma basta):

1. **Flag de invocação** (ad-hoc, por execução):
   ```
   /fork-manager --auto-resolve
   /fork-manager full-sync --auto-resolve
   ```
2. **Config persistente** (sempre ativo pra aquele repo):
   ```json
   { "autoResolveConflicts": true }
   ```

| Fonte | Comportamento |
|-------|---------------|
| Nenhuma (default) | Conflitos são reportados mas **não resolvidos**. Relatório inclui "⚠️ Conflitos requerem aval do desenvolvedor." |
| `--auto-resolve` OU `config.autoResolveConflicts: true` | Spawna subagentes Opus para resolver conflitos. Resultados classificados como trivial/semântico/irresolvível. |

**Precedência:** `--auto-resolve` na invocação ativa a resolução mesmo se o config diz `false`. Não existe `--no-auto-resolve` — se o config diz `true` e o usuário não quer resolver, basta não rodar o passo manualmente.

**Para usuários do ClawHub:** basta passar `--auto-resolve` no comando. Nenhuma configuração de repo necessária.

### Campos de `localPatches`

Cada entry em `localPatches` é uma branch local mantida na production branch mas **sem PR aberto** no upstream.

| Campo | Descrição |
|-------|-----------|
| `description` | O que o patch faz |
| `originalPR` | Número do PR original que foi fechado (opcional se criado direto como patch) |
| `closedReason` | Por que o PR foi fechado: `rejected` (mantenedor recusou), `superseded` (outro PR resolve parcialmente mas não totalmente), `duplicate` (fechamos nós mesmos), `wontfix` (upstream não vai resolver) |
| `keepReason` | Por que precisamos manter localmente |
| `addedAt` | Data em que foi convertido para local patch |
| `reviewDate` | Data para reavaliar se ainda é necessário (upstream pode ter resolvido) |

## Histórico de Execuções

Cada repositório gerenciado tem um arquivo `history.md` que registra todas as execuções da skill como um livro de registro append-only:

```
fork-manager/
└── repos/
    ├── project-a/
    │   ├── config.json
    │   └── history.md
    └── project-b/
        ├── config.json
        └── history.md
```

### Regra: Ler último output antes de começar

**Antes de qualquer operação**, ler o `history.md` do repositório alvo e extrair a **última entrada** (último bloco `---`). Isso dá contexto sobre:
- O que foi feito na última execução
- Quais PRs tinham problemas
- Quais decisões foram tomadas
- Se ficou alguma ação pendente

```bash
# Ler última entrada do history (tudo após o último "---")
tail -n +$(grep -n '^---$' "$SKILL_DIR/repos/<repo-name>/history.md" | tail -1 | cut -d: -f1) "$SKILL_DIR/repos/<repo-name>/history.md"
```

Se o arquivo não existir, criar com o header e prosseguir normalmente.

### Regra: Registrar output ao finalizar

**Ao final de toda execução**, fazer append ao `history.md` com o resultado completo. Formato:

```markdown
---
## YYYY-MM-DD HH:MM UTC | <comando>
**Operator:** <claude-code | openclaw-agent | manual>

### Summary
- Main: <status do sync>
- PRs: <X open, Y merged, Z closed, W reopened>
- Local Patches: <N total, M co