CLI Spec

CLI Spec

Command

The executable is:

contribflow

The short alias is:

cflow

The CLI is the primary product interface.

Global Behavior

Every command that returns meaningful structured data must support:

--json

Human output should be concise and actionable. JSON output should be stable enough for agents and automation.

The CLI should use the local GitHub CLI for GitHub auth in v0:

gh auth status

No GitHub OAuth setup should be required for CLI usage.

Initial Commands

contribflow --help

Print available commands and examples.

contribflow init

Create local configuration:

.contribflow/config.json

Default config:

{
  "languages": [],
  "topics": [],
  "contributionTypes": [],
  "difficulty": "beginner_to_intermediate",
  "maxChangedFiles": 8,
  "maxLinesChanged": 300,
  "requireHumanApproval": true,
  "draftPrByDefault": true,
  "aiDisclosure": true
}

contribflow status --json

Check:

  • current working directory
  • config presence
  • GitHub CLI auth status
  • active contribution state
  • next recommended action

contribflow discover --json

Discover GitHub issue candidates from local config and optional flags:

contribflow discover --lang go --topic observability --json

Supported initial flags:

  • --lang <language> repeatable
  • --topic <topic> repeatable
  • --type <contributionType> repeatable
  • --limit <number>
  • --json

Discovery fetches a larger GitHub search pool than the requested limit, scores candidates with the local contribution profile, sorts by score and repository signal, and suppresses stale, duplicate, security-sensitive, and low-signal dependency automation candidates from the default candidate list.

When GitHub issue search hits primary search exhaustion or secondary protection, discovery returns a structured blocked result instead of a generic CLI error:

{
  "status": "blocked",
  "nextAction": "wait_or_refine_discovery",
  "recommendedCommand": "gh api rate_limit --jq '.resources.search'",
  "blocked": {
    "kind": "search_rate_limit",
    "scope": "discovery_query",
    "failingQuery": "is:issue is:open archived:false",
    "retryAfterSeconds": null,
    "retryAfterAt": null
  }
}

Agents must not immediately retry the same blocked.failingQuery. Wait for GitHub search protection to cool down, inspect search quota, or rerun discovery with narrower --lang, --topic, or --type flags.

contribflow score owner/repo#123 --json

Fetch one GitHub issue and return:

  • candidate metadata
  • score
  • score breakdown
  • score explanation
  • recommendation
  • risk flags
  • duplicate evidence from open PR issue-reference searches, title-similarity searches, and direct existing-content checks for quoted requested content
  • next recommended action

Direct scoring uses .contribflow/config.json when present. The breakdown includes profileFit for language, topic, contribution type, difficulty, and patch-size preference alignment.

contribflow plan owner/repo#123 --json

Fetch and score one GitHub issue, inspect repository guidance and structure, then generate a deterministic contribution plan:

  • issue metadata
  • short summary
  • proposed minimal fix
  • likely files
  • detected repository guidance files
  • likely validation commands from package scripts
  • test plan
  • PR title/body guidance
  • stop conditions
  • risk assessment
  • assumptions and open questions
  • human approval guidance
  • next recommended action

contribflow checkout owner/repo#123 --json

Create or reuse a local workspace under .contribflow/workspaces, clone the public GitHub repository, create a contribflow/issue-123 branch, and capture command logs under .contribflow/logs.

The checkout command must not execute target repository code. It may run git clone, git checkout, git status, and git submodule status.

JSON output includes:

  • issue reference
  • repository full name
  • controller workspace path
  • runFrom, the recommended directory for stateful follow-up commands
  • workspace path
  • branch name
  • clean state
  • checkout log path
  • whether the workspace was created
  • declared submodule status and safe initialization command, when applicable

Checkout reports declared submodules but does not initialize them automatically. If submodules require initialization, the safe follow-up command is:

git -C .contribflow/workspaces/owner-repo-123 submodule update --init --recursive

Stateful commands such as diff, validate, pr, and next read controller state from .contribflow/state.json. They can be run from the initialized ContribFlow workspace root or from any managed checkout path under .contribflow/workspaces/<slug>.

contribflow diff [owner/repo#123] --json

Capture a local patch artifact from an existing workspace.

When the issue reference is omitted, the command uses the active workspace issue from .contribflow/state.json.

The diff command must not perform public GitHub actions and must not execute target repository code. It may run local git status and git diff commands inside the workspace.

JSON output includes:

  • issue reference
  • workspace path
  • artifact path
  • changed files summary
  • unified diff
  • sensitive-file and duplicate-content risk flags
  • whether changes exist
  • next recommended action

contribflow validate --json

Inspect the active workspace from .contribflow/state.json, detect likely dependency setup and validation commands, and return a validation summary. The CLI resolves controller state from the current directory or an ancestor, so validation can run from the controller root or from inside the managed checkout.

Default safety policy: the CLI must not execute arbitrary target repository code on the host. Without explicit execution flags, detected commands are reported with status: "blocked" and blocksPr: true.

When a patch artifact exists, validation also inspects changed files for nested package manifests. Nested commands include workingDirectory in JSON output and run from that directory inside the Docker sandbox. Lockfile requirements apply to each validation scope.

To run detected commands, use an explicit Docker sandbox:

contribflow validate --run --sandbox docker --json

The Docker runner uses a two-phase policy:

  • mounts only the active workspace at /work
  • does not pass host secrets or GitHub credentials into the container
  • applies CPU, memory, process, capability, and no-new-privileges limits
  • redacts and truncates command output in JSON

Dependency setup runs first only when the repository has a supported reproducible setup path:

  • package-lock.json: npm ci --ignore-scripts
  • pnpm-lock.yaml: pnpm install --frozen-lockfile --ignore-scripts
  • yarn.lock: YARN_ENABLE_SCRIPTS=false yarn install --immutable
  • go.mod: go mod download

The setup phase may use container network access to download dependencies. Validation commands then run in a separate Docker invocation with --network none. Package-manager setup without the expected lockfile must block validation and PR creation.

For Go workspaces, Docker image selection reads toolchain goX.Y first and then go X.Y from go.mod. Both go commands and Makefile commands in Go workspaces use the matching golang:X.Y-bookworm image.

Repos with native/system dependencies can use a prebuilt validation image:

contribflow validate --run --sandbox docker --sandbox-image ghcr.io/acme/project-validation:go1.26 --json

The image should already contain required OS packages. ContribFlow does not run arbitrary host setup commands or pass host secrets into the container.

Supported execution flags:

  • --run
  • --sandbox docker
  • --sandbox-image <image>
  • --timeout-ms <milliseconds>

JSON output includes:

  • workspace path
  • detected setup commands
  • detected validation commands
  • per-command status
  • sandbox metadata when commands are executed
  • suggested system packages when common missing native headers are detected
  • redacted stdout/stderr snippets when commands are executed
  • PR blocking status
  • reason
  • next recommended action

contribflow pr --draft --json

Inspect the active workspace, patch artifact, and latest validation result, then return a draft PR dry-run preview.

Default PR behavior must not perform GitHub writes. The dry-run path returns:

  • target repository
  • issue reference
  • branch
  • title
  • PR body preview
  • changed files
  • validation status
  • planned commands
  • review gate checks
  • human approval requirement

PR creation is blocked unless:

  • an active workspace exists
  • a patch artifact exists and contains changes
  • changed file count and changed line count stay within .contribflow/config.json limits
  • the patch artifact reports no sensitive files
  • the patch artifact reports no duplicate content warnings
  • .contribflow/validation.json records passing sandbox validation for the active workspace
  • planned public commands are listed in wouldRun
  • the PR body contains the ContribFlow AI disclosure
  • the PR is draft

When all checks pass, the dry-run result includes reviewGate.state: "ready_for_human_review", nextAction: "human_review", and requiresHumanApproval: true. Agents must stop at this state.

contribflow pr --draft --yes --json

Create a draft PR only after explicit approval through --yes.

The approved path is blocked unless a prior contribflow pr --draft --json result exists for the same active workspace with reviewGate.state: "ready_for_human_review".

The approved path uses local gh and git to:

  • verify gh auth status
  • resolve the authenticated GitHub user
  • resolve the repository default branch
  • commit the current workspace patch
  • create or reuse a fork
  • push the contribution branch to the fork
  • open a draft PR with AI disclosure

Agents must ask the user before running this command because it performs public GitHub writes.

contribflow next --json

Inspect local ContribFlow state and return the next recommended CLI action without performing writes.

The next command reads:

  • .contribflow/config.json
  • GitHub CLI auth status
  • active workspace state
  • patch artifact
  • validation result
  • PR dry-run or created result
  • human review gate checks before any public write

JSON output includes:

  • workflow state
  • next action
  • recommended command
  • human approval requirement
  • reason

The command must prefer CLI/core actions over dashboard actions.