kedgeway

Docs / Use / Commands

Commands

Eight commands: diagnose, init, login, logout, doctor, migrate, pr and mcp. Plus --version.

--version

Terminal
kedgeway --version
kedgeway -V

Prints the installed version, read from package.json, and exits with 0.

diagnose

Terminal
kedgeway diagnose [path-or-url] [--ref <ref>] [--json] [--format <text|json|sarif|annotations>] [--sarif <file>] [--annotations <file>] [--fixture <file>] [--fail-on <severity>] [--offline] [--no-cache] [--max-age <duration>]

Scans the repo at path-or-url (default: the current directory), fetches ecosystem data, and prints a report. Raven is used unless you pass --fixture. The source is a local path, a git URL (https://, ssh:// or git@host:owner/repo) or the GitHub shorthand owner/repo. An existing local directory takes precedence over the shorthand. A remote source is shallow-cloned into a temporary directory and deleted afterwards. See Remote repositories.

--ref <ref>
Branch or tag to scan when the source is a remote repository. It may repeat the /tree/<ref> of the URL but not contradict it. With a local path it is an error and exits with 1. Also on migrate.
--json
Print the diagnosis as JSON instead of text. The object has findings (each with severity, code, message, file, evidence) and summary (critical, warning, info).
--format <text|json|sarif|annotations>
Choose the stdout format. --json is the same as --format json; using both exits with 1. annotations prints one GitHub workflow command per finding (::error, ::warning, ::notice, with the manifest file and line), then the normal text report.
--sarif <file>
Also write a SARIF 2.1.0 log to file. Stdout still follows --format.
--annotations <file>
Also write the GitHub annotations to file. Stdout still follows --format. The line is a best-effort scan of the manifest. See GitHub Action.
--offline
Use the cached ecosystem snapshot only and never call Raven. Exits 1 if there is no cache; contradicts --no-cache; ignored with a warning when --fixture is set. Also on migrate. On doctor the same flag only skips the Raven reachability check.
--no-cache
Ignore the cached snapshot and fetch live. The result is still written to the cache. Also on migrate.
--max-age <duration>
How old a cached snapshot may be before it is refetched: 30s, 15m, 24h, 2d. Default 24h. Also on migrate. See Data sources.
--fixture <file>
Read the ecosystem snapshot from a JSON file instead of calling Raven. No login needed. See Fixtures.
--fail-on <severity>
Exit with code 2 if any finding is at or above critical, warning or info. Any other value is an error and exits with 1.
Terminal
kedgeway diagnose ./my-contract --fail-on critical
kedgeway diagnose . --json > report.json
kedgeway diagnose https://github.com/o/r
kedgeway diagnose o/r --ref v1.2.0 --fail-on warning

init

Terminal
kedgeway init [path] [--force] [--print] [--mode <diagnose|pr>]

Writes .github/workflows/kedgeway.yml under path (default: the current directory). The workflow runs on pushes to main or master and on pull requests, and uses Klorenn/kedgeway@v<installed version> with path: ., fail-on: warning and auth: ${{ secrets.KEDGEWAY_AUTH }}. Afterwards, create the KEDGEWAY_AUTH repository secret from the output of kedgeway login --export. See GitHub Action.

--force
Overwrite an existing workflow file. Without it, an existing file is left as is and the command exits with 1.
--print
Print the workflow YAML to stdout and write nothing.
--mode <diagnose|pr>
Which workflow to write. diagnose (the default) writes kedgeway.yml as described above. pr writes .github/workflows/kedgeway-pr.yml instead: a weekly job (Mondays at 09:00 UTC, plus workflow_dispatch) with contents: write and pull-requests: write, actions/checkout with fetch-depth: 0, and the action with mode: pr. It then reminds you to allow GitHub Actions to create pull requests. See Open a migration PR.

Exit 0 on success. Exit 1 if the file exists and --force is not set, or if the write fails.

login

Terminal
kedgeway login

Starts a fresh OAuth authorization with Stellar Raven and stores the token. Prints Logged in to Stellar Raven. on success. See Authentication.

Terminal
kedgeway login --no-browser

login --no-browser is for machines without a browser. It prints the authorization URL instead of opening it. Open the URL anywhere, sign in, then paste the redirect URL (or just its code) back into the terminal. A pasted URL is checked against the login attempt's OAuth state; a bare code carries none. Or forward the callback port with ssh -L and let the redirect land on kedgeway directly. It combines with --export. See Headless login.

Terminal
kedgeway login --export

login --export prints your stored credentials as a base64 secret for CI and removes nothing. It logs in first only when nothing is stored, and it opens a browser unless you also pass --no-browser. Stdout is the secret; stderr warns that it is one. If KEDGEWAY_AUTH is already set in the environment, that value is ignored and the stored login is what gets exported. Put the output in a KEDGEWAY_AUTH secret. See CI.

logout

Terminal
kedgeway logout

Deletes the stored credentials. It prints whether anything was removed and exits with 0 either way.

doctor

Terminal
kedgeway doctor [--offline]

A self-check that changes nothing. It prints one line per check, ok, warn, fail or skip:

  • Node version (22.12 or newer).
  • Auth: a valid KEDGEWAY_AUTH in the environment, an auth.json with tokens, or none.
  • Snapshot cache: path and age.
  • Stellar CLI: runs stellar --version without a shell (5 second timeout). Not installed is warn, since it is optional (install guide). With a cached snapshot, the current major or newer is ok, one major behind is warn, and two or more is fail. With --offline or no snapshot it is ok and only reports the installed version.
  • Raven reachability: one cheap search call with a 10 second timeout. --offline skips it. It uses a read-only copy of your credentials, so a token refresh cannot modify auth.json.

Exit 0 when nothing failed (warnings do not fail it), 1 when any check failed.

migrate

Terminal
kedgeway migrate [path-or-url] [--ref <ref>] [--dry-run] [--write] [--fixture <file>] [--offline] [--no-cache] [--max-age <duration>]

Prints a migration guide and a unified diff of SDK version bumps. The default is a dry run, and --dry-run is that same mode made explicit. --write applies the manifest edits. Passing both --dry-run and --write exits 1. --offline, --no-cache and --max-age behave as they do on diagnose. Exit 0 for nothing to do, a manual-only dry run, or edits applied; 2 for a dry run with at least one automatic edit, or a write where some step was skipped; 1 on error, including a refused write. It edits manifests only and notes any lockfile it leaves stale, with a manual step to refresh it. See Migration guide.

path-or-url accepts the same sources as diagnose. Migrating a remote source is a dry run only: --write exits with 2 and prints remote sources are dry-run only; clone it and run migrate locally.

Terminal
kedgeway migrate https://gitlab.com/group/sub/r

pr

Terminal
kedgeway pr [path] [--dry-run] [--base <branch>] [--branch <name>] [--repo <owner/repo>] [--token <token>] [--refresh-lockfiles] [--label <name>] [--draft] [--json]

Turns the migrate plan into a pull request. Run it inside a local checkout of the repository; it uses your Raven login and your GITHUB_TOKEN, and there is no hosted service. A run does three things:

  1. Plans the migration on a clean working tree. A dirty tree exits 2, unless --dry-run. When there is no automatic edit, it prints the reason and exits 0 without touching git or the network.
  2. Creates, or resets, the branch kedgeway/migrate-<major> (kedgeway/migrate-toolchain when there is no concrete target major) from origin/<base> (never from local HEAD, so unpushed local commits never reach the PR), applies the same edits as migrate --write, optionally refreshes lockfiles, and commits only the files it edited plus any lockfiles it refreshed (never git add -A) as kedgeway[bot] <kedgeway@users.noreply.github.com>. Set KEDGEWAY_GIT_AUTHOR_NAME and KEDGEWAY_GIT_AUTHOR_EMAIL to change the author. Hooks and signing are off for that commit.
  3. Force-pushes that branch with --force-with-lease, so commits a human added to the PR branch are not silently overwritten, then creates the pull request or updates the one already open for it, applies the label, and prints the PR URL. The branch is kedgeway's own, so use a name nothing else writes to.

There is only ever one open PR per branch. The branch name comes from the plan, so the same migration always lands on the same branch. If an open PR already has that branch as its head, kedgeway updates its title and body and the force-push refreshes its commits; otherwise it opens a new one. A closed or merged PR does not block a new run. When the target major changes, the branch name changes too, so a new PR is opened and the old one stays open for you to close.

The pull request contains:

  • A title such as chore(deps): migrate soroban-sdk to 28 (at most 72 characters), or chore(toolchain): kedgeway migration.
  • A summary line of what moves from and to.
  • A findings table with code, severity and file:line.
  • The edits.
  • The manual steps, as a checklist.
  • The migration guide.
  • A lockfiles note when a lockfile pins a changed dependency and still needs refreshing.
  • Notes about anything that could not be applied or refreshed.
  • The provenance (snapshot source and observedAt) and the footer Opened by kedgeway <version>.
--dry-run
Print the title and body. No git writes and no network at all. Works on a dirty tree and needs no token.
--base <branch>
Branch the PR targets. Default: the repository's default branch from the API, falling back to the current branch with a warning.
--branch <name>
Head branch to push. Default kedgeway/migrate-<major>. It must start with kedgeway/; anything else exits 2 before anything is pushed. It may never equal the base branch, the repository default branch or the checked-out branch. Letters, digits and ._/- only.
--allow-any-branch
Lifts only the kedgeway/ prefix rule of --branch, for a name that only kedgeway writes, because the branch is force-pushed. The branch may still never equal the base, the default branch or the checked-out branch. CLI only: the MCP pr tool and the action's pr-branch input do not have it.
--repo <owner/repo>
GitHub repository. Default GITHUB_REPOSITORY, else parsed from git remote get-url origin.
--token <token>
GitHub token. Default GITHUB_TOKEN. Prefer the environment variable: argv is visible to other users.
--refresh-lockfiles
Refresh only the lockfiles the plan touched, and only when the tool is installed: cargo update -p soroban-sdk, npm install --package-lock-only, pnpm install --lockfile-only, yarn install --mode update-lockfile (npm and pnpm also get --ignore-scripts). Off by default. A failure becomes a note in the PR body, not a crash.
--label <name>
Label to apply. Default kedgeway, created if missing. A label failure is a warning, not an error.
--draft
Open the PR as a draft.
--json
Print { action, url?, branch, title }. action is create, update, skip or dry-run; skip adds reason and dry-run adds body.
--fixture, --offline, --no-cache, --max-age
As on diagnose and migrate.
Terminal
kedgeway pr --dry-run
kedgeway pr --draft --refresh-lockfiles

Exit 0 when the PR was created or updated, or the run was skipped. Exit 1 on a git or API failure. Exit 2 on a usage error: a dirty tree, a missing token or repository, a bad --branch or --repo, a remote URL source, or contradictory cache flags.

Only manifest version strings change, plus the lockfiles you opt into. Source code is never rewritten, so CI on the PR is your safety net. Local paths only. To run it on a schedule, use kedgeway init --mode pr; see GitHub Action.

mcp

Terminal
kedgeway mcp [--allow-write]

Runs an MCP server over stdio. It never starts OAuth: log in first. --allow-write lets the migrate tool edit files and the pr tool open pull requests; without it, write: true returns an error and dry runs still work. See MCP server.

Exit codes

CodeMeaning
0diagnose: finished, and no --fail-on threshold was hit. migrate: nothing to do, only manual steps, or the edits were applied. pr: the PR was created or updated, or the run was skipped. init: the workflow was written, or printed with --print. doctor and logout: finished. A warn from doctor still exits 0.
1Tool error: an invalid flag (including --fail-on, --format or --max-age), --json combined with --format, --offline with --no-cache, a login failure, a pr git or API failure (including GitHub's 403 when Actions may not create pull requests), a failed doctor check, init finding an existing workflow without --force or failing to write it, or a scan or network failure.
2diagnose: a finding met --fail-on. migrate: a dry run has an automatic edit, --write skipped a step, or --write was passed with a remote source. pr: a usage error, such as a dirty tree, a missing token or repository, a bad --branch or --repo, a remote URL source, or contradictory cache flags. doctor never exits 2.

logout exits 0 whether or not a credentials file was deleted. --help exits 0. An unknown command or flag exits 1.