Docs / Use / Commands
Commands
Eight commands: diagnose, init, login, logout, doctor, migrate, pr and mcp. Plus --version.
--version
kedgeway --version
kedgeway -VPrints the installed version, read from package.json, and exits with 0.
diagnose
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 onmigrate. --json- Print the diagnosis as JSON instead of text. The object has
findings(each withseverity,code,message,file,evidence) andsummary(critical,warning,info). --format <text|json|sarif|annotations>- Choose the stdout format.
--jsonis the same as--format json; using both exits with 1.annotationsprints 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--fixtureis set. Also onmigrate. Ondoctorthe 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. Default24h. Also onmigrate. 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,warningorinfo. Any other value is an error and exits with 1.
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 warninginit
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) writeskedgeway.ymlas described above.prwrites.github/workflows/kedgeway-pr.ymlinstead: a weekly job (Mondays at 09:00 UTC, plusworkflow_dispatch) withcontents: writeandpull-requests: write,actions/checkoutwithfetch-depth: 0, and the action withmode: 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
kedgeway loginStarts a fresh OAuth authorization with Stellar Raven and stores the token. Prints Logged in to Stellar Raven. on success. See Authentication.
kedgeway login --no-browserlogin --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.
kedgeway login --exportlogin --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
kedgeway logoutDeletes the stored credentials. It prints whether anything was removed and exits with 0 either way.
doctor
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_AUTHin the environment, anauth.jsonwith tokens, or none. - Snapshot cache: path and age.
- Stellar CLI: runs
stellar --versionwithout a shell (5 second timeout). Not installed iswarn, since it is optional (install guide). With a cached snapshot, the current major or newer isok, one major behind iswarn, and two or more isfail. With--offlineor no snapshot it isokand only reports the installed version. - Raven reachability: one cheap
searchcall with a 10 second timeout.--offlineskips it. It uses a read-only copy of your credentials, so a token refresh cannot modifyauth.json.
Exit 0 when nothing failed (warnings do not fail it), 1 when any check failed.
migrate
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.
kedgeway migrate https://gitlab.com/group/sub/rpr
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:
- 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. - Creates, or resets, the branch
kedgeway/migrate-<major>(kedgeway/migrate-toolchainwhen there is no concrete target major) fromorigin/<base>(never from local HEAD, so unpushed local commits never reach the PR), applies the same edits asmigrate --write, optionally refreshes lockfiles, and commits only the files it edited plus any lockfiles it refreshed (nevergit add -A) askedgeway[bot] <kedgeway@users.noreply.github.com>. SetKEDGEWAY_GIT_AUTHOR_NAMEandKEDGEWAY_GIT_AUTHOR_EMAILto change the author. Hooks and signing are off for that commit. - 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), orchore(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 footerOpened 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 withkedgeway/; 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 MCPprtool and the action'spr-branchinput do not have it. --repo <owner/repo>- GitHub repository. Default
GITHUB_REPOSITORY, else parsed fromgit 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 }.actioniscreate,update,skipordry-run;skipaddsreasonanddry-runaddsbody. --fixture, --offline, --no-cache, --max-age- As on
diagnoseandmigrate.
kedgeway pr --dry-run
kedgeway pr --draft --refresh-lockfilesExit 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
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
| Code | Meaning |
|---|---|
0 | diagnose: 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. |
1 | Tool 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. |
2 | diagnose: 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.