Skip to content

Usage

This page walks through the workflows forkctl was built for. Each example uses the CLI; the MCP tool name is shown in parentheses so you can call them from Claude or another client too.

You found an open-source repo, you want to fork it, you want it to actually work, and you want to send PRs back upstream.

Terminal window
# 1. Score it before you commit any time
forkctl assess octocat/hello-world
# 2. Confirm the right path for your goal
forkctl choose-path octocat/hello-world --goal contribute_upstream
# → recommends fork
# 3. Preflight the fork policy (catches org/enterprise blockers up front)
forkctl preflight-policy octocat/hello-world
# 4. Kick off the async fork
forkctl create-fork octocat/hello-world --destination-org my-org
# → { "operationId": "...", "status": "pending" }
# 5. Wait for GitHub to finish
forkctl check-operation <operationId>
# 6. Apply the contributor profile (upstream wiring, sync workflow, PR template)
forkctl bootstrap my-org/hello-world \
--source octocat/hello-world \
--profile contributor
# 7. Scan for drift (hardcoded paths, leaked secrets, stale refs)
forkctl scan-drift my-org/hello-world --source octocat/hello-world
# 8. Get the truthful handoff artifact
forkctl emit-handoff my-org/hello-world \
--source octocat/hello-world \
--profile contributor

The handoff artifact is a single JSON receipt with clone commands, upstream wiring, drift caveats, and the recommended next action.

Workflow 2 — Improve a source repo (make_forkable)

Section titled “Workflow 2 — Improve a source repo (make_forkable)”

You own a repo and want it to be more adoptable. Default mode is plan (no writes); pr mode opens a branch + PR with the suggested fixes.

Terminal window
# Plan mode — shows what would change
forkctl make-forkable my-org/my-product
# PR mode — opens an actual PR with a default MIT LICENSE,
# README seed, .env.example, CONTRIBUTING.md, SECURITY.md
forkctl make-forkable my-org/my-product --mode pr

Generated content is conservative starter material. Always review before merging — the goal is to remove blockers, not to author your final docs.

Terminal window
# Best practice: diagnose before syncing
forkctl diagnose-divergence myhandle/my-fork
# If status is 'behind' or 'identical', sync is a fast-forward:
forkctl sync myhandle/my-fork
# If status is 'diverged', sync will return SYNC_CONFLICT.
# Open a PR-based sync instead (never force-pushes):
forkctl propose-sync-pr myhandle/my-fork
Terminal window
# What forks do I have?
forkctl list-forks
# Which ones need attention?
forkctl fleet-health
# → sorted: diverged > behind > ahead > in_sync > no_upstream > error
# Sync many at once (sequential, rate-limit-friendly)
forkctl batch-sync me/fork-a me/fork-b me/fork-c \
--fail-fast-after 3

Conflicts surface as outcome: conflict — never as errors and never as silent overwrites.

Workflow 5 — Generate a fresh repo from a template

Section titled “Workflow 5 — Generate a fresh repo from a template”
Terminal window
forkctl create-from-template templator/seed \
--owner my-org \
--name fresh-product \
--private \
--description "Our new product"
forkctl check-operation <operationId>
forkctl bootstrap my-org/fresh-product --profile starter-kit

The starter-kit profile strips template references, freshes the README, prompts a license update, and ensures .env.example exists.

ProfileForAftercare
contributorForking to send PRs upstreamUpstream remote, sync workflow, PR template
starter-kitGenerated from a templateStrip template refs, fresh README, .env.example
internal-seedInternal team copy of a shared seedReplace placeholders, CODEOWNERS, lock visibility
client-deliveryPer-client fork of a deliverableClient branches, sanitized history check, locked default branch
experimentThrowaway / detached copyDetach upstream, mark as experiment in README

Every operation is recorded in a local SQLite store and audit log.

Terminal window
# Look up a single operation
forkctl receipt <operationId>
# Query the audit log
forkctl audit-log --tool forkctl_create_fork --limit 20
forkctl audit-log --ok false --limit 50

Tokens and known sensitive keys (token, GITHUB_TOKEN, password, secret, apiKey, api_key) are redacted at write time. GitHub PAT patterns inside string values are also redacted.