Skip to content

Tool Reference

Every tool is a ToolDescriptor<TInput, TOutput> with a Zod-validated input schema. The MCP and CLI surfaces both call the same handlers through the central dispatch() boundary.

Score a repo’s adoption-readiness across six categories (legal, setup, contribution, hygiene, template, sync).

FieldTypeNotes
repoowner/repoRequired
goalGoalOptional context

Returns AdoptionReport: score (0–100), blockers[], strengths[], nextActions[] (top 5), categories[].

CLI: forkctl assess <repo>

Recommend fork | template | import | clone_detached for a given source + goal.

FieldTypeNotes
repoowner/repoRequired
goalcontribute_upstream | ship_derivative | internal_seed | client_copy | experimentRequired

Decision logic:

  • contribute_upstream → fork (only path that preserves upstream link)
  • ship_derivative → template if isTemplate, else clone_detached
  • internal_seed → template if available, else fork
  • client_copy → template if available, else clone_detached
  • experiment → fork

Override: if fork is policy-blocked and a template is available, downgrades to template.

CLI: forkctl choose-path <repo> --goal <goal>

Generate a patch plan (default) or open a PR (opt-in) that fixes the source repo’s adoption blockers.

FieldTypeDefault
repoowner/reporequired
modeplan | prplan
branchstringforkctl/adoption-fixes

Generators cover: NO_LICENSE, NO_README, NO_ENV_EXAMPLE, NO_CONTRIBUTING, NO_SECURITY.

CLI: forkctl make-forkable <repo> [--mode pr] [--branch <name>]

Resolve fork policy across the enterprise → org → repo cascade. Catches:

  • Archived source
  • allow_forking: false at the repo level
  • members_can_fork_private_repositories: false at the org level

Returns ForkPolicyVerdict with allowed: yes | no | unknown and a reason.

CLI: forkctl preflight-policy <repo>

Kick off an async fork. Records a pending operation; returns immediately.

FieldTypeNotes
sourceowner/repoRequired
destinationOrgstringOptional — defaults to authenticated user
namestringOptional fork rename
defaultBranchOnlybooleanDefault false

Returns { operationId, status, destination, destinationUrl, message }.

CLI: forkctl create-fork <source> [--destination-org <org>] [--name <name>] [--default-branch-only]

Generate a new repo from a template via POST /repos/{owner}/{repo}/generate.

FieldTypeNotes
templateowner/repoRequired
ownerstringRequired (new repo owner)
namestringRequired (new repo name)
descriptionstringOptional
privatebooleanDefault false
includeAllBranchesbooleanDefault false

CLI: forkctl create-from-template <template> --owner <owner> --name <name> [...]

Idempotent single-probe poller. For pending fork/template ops, performs one repos.get against the destination; updates state on success.

CLI: forkctl check-operation <operationId>

Apply a profile’s step sequence to a destination repo.

FieldTypeDefault
destinationowner/reporequired
sourceowner/repooptional
profileProfileIdrequired
applybooleantrue

Returns per-step outcome (applied | skipped | advisory | failed) plus a summary.

CLI: forkctl bootstrap <destination> --profile <id> [--source <source>] [--no-apply]

Wire upstream sync. Returns the canonical git remote add upstream command sequence and optionally installs .github/workflows/sync-upstream.yml.

CLI: forkctl configure-upstream <destination> --source <source> [--branch main] [--no-install-workflow]

Scan a destination repo for hardcoded local paths, leaked secrets (GitHub PAT, AWS, OpenAI, Google), and stale source-owner references. Secret values are never echoed — evidence: "<redacted>".

CLI: forkctl scan-drift <destination> [--source <source>]

Single, truthful handoff artifact. Combines clone commands, upstream wiring, drift caveats, and a single next-action sentence. High-severity caveats override the next action.

CLI: forkctl emit-handoff <destination> [--source <source>] [--profile <id>]

Calls POST /repos/{owner}/{repo}/merge-upstream. Returns mergeType: fast-forward | merge | none. On 409 conflict, raises SYNC_CONFLICT with a hint pointing at propose_sync_pr. Never force-pushes.

CLI: forkctl sync <fork> [--branch <name>]

Read-only. Uses the cross-repo compare API. Returns status: ahead | behind | identical | diverged, aheadBy, behindBy, files at risk, and a fastForwardable boolean.

CLI: forkctl diagnose-divergence <fork> [--branch <name>]

PR-based sync for diverged forks. Creates a branch on the fork pointing at the upstream HEAD SHA (works because forks share git storage with their parent), then opens a PR into the fork’s branch.

CLI: forkctl propose-sync-pr <fork> [--branch <name>] [--sync-branch <name>] [--pr-title <title>]

List the authenticated user’s forks (default) or forks of a specific source.

CLI: forkctl list-forks [--source <owner/repo>] [--limit <n>]

Health-check a set of forks. Sorts diverged + behind to the top.

CLI: forkctl fleet-health [--limit <n>]

Sequential sync across many forks. Stops after failFastAfter consecutive non-success outcomes (conflict + error).

CLI: forkctl batch-sync <fork>... [--branch <name>] [--fail-fast-after <n>]

Machine-readable receipt for an operation. Returns the operation record + every audit entry that referenced it + a one-line summary.

CLI: forkctl receipt <operationId>

Query the append-only audit log. Filter by tool, operation id, ok flag, sinceMs.

CLI: forkctl audit-log [--tool <name>] [--operation-id <id>] [--ok <true|false>] [--limit <n>]

The rename layer works on a local working tree rather than through the GitHub API. It performs an AST-aware coherent rename across identity files, code symbols, non-code textual surfaces, and a post-pass that regenerates lockfiles and emits an asset-regeneration manifest. See Rename for a walkthrough.

Read-only. Analyse the tree and produce a RenamePlan with the intended diff per layer, plus the human-reviewable file .forkctl/rename-plan.diff.

FieldTypeNotes
pathstringRepo root (absolute or relative)
fromstringCanonical old name (e.g. forkctl)
tostringCanonical new name (e.g. splitshift)
layers("identity" | "symbols" | "deep-ts" | "textual" | "post")[]Default: all except deep-ts (auto when tsconfig resolves)
excludestring[]Glob patterns added to built-in excludes
lockfileStrategy"regenerate" | "skip"Default "regenerate"
deepTsbooleanAuto when tsconfig.json + ts-morph resolvable

Returns a RenamePlan — casing variant map, per-layer dry-run report, warnings (including STRING_LITERAL_REWRITTEN and ENV_REQUIRES_REVIEW).

CLI: forkctl rename plan <path> --from <old> --to <new> [--exclude <glob>] [--no-deep-ts]

Consumes a RenamePlan. Snapshots the tree first, then runs the five passes in order (identity → symbols → deep-ts → textual → post). Returns a RenameReceipt with per-layer outcomes, paths moved, lockfiles regenerated, and any assets flagged for regeneration.

FieldTypeNotes
pathstringRepo root
planstringPath to the .forkctl/rename-plan.json produced by plan
planHashstringOptional — defends against stale plans (fails with RENAME_PLAN_STALE)

CLI: forkctl rename apply <path> --plan .forkctl/rename-plan.json

Restores from the latest snapshot. For git repos, git reset --hard <pre-rename-HEAD> + stash pop. For non-git repos, extracts the snapshot tarball.

FieldTypeNotes
pathstringRepo root

CLI: forkctl rename rollback <path>

If no snapshot exists, returns RENAME_ROLLBACK_NOT_FOUND. Snapshots are kept for 7 days.

Every tool returns:

type ToolResult<T> =
| { ok: true; data: T }
| { ok: false; error: { code: ForkctlErrorCode; message: string; hint?: string; details?: unknown } };

Error codes are exhaustively enumerated in src/lib/errors.ts — see the Architecture page for the full list.