Skip to content

feat: add sf migrate command and Rust CLI migration banner#266

Open
sigmachirality wants to merge 4 commits into
mainfrom
indent-2026-05-21-migrate-banner
Open

feat: add sf migrate command and Rust CLI migration banner#266
sigmachirality wants to merge 4 commits into
mainfrom
indent-2026-05-21-migrate-banner

Conversation

@sigmachirality
Copy link
Copy Markdown
Member

Summary

When no upgrade banner is shown on startup, the legacy CLI now nudges users to migrate to the new Rust-based sf (blueprint/preview docs). Adds a sf migrate subcommand that runs the new install script from https://cli.sfcompute.com.

Motivation

sf-cli (the Rust replacement living in sfcompute/sfcompute) is the path forward. We want every invocation of the legacy CLI to surface that path — but only when we're not already asking the user to upgrade the current binary, to avoid double-stacking banners.

The new install script at cli.sfcompute.com already moves the existing sf binary to sf-old, so users keep access to the legacy CLI during the transition. The banner and sf migrate output both call that out.

Changes

  • src/checkVersion.tscheckVersion() now returns boolean indicating whether an upgrade banner was shown (or an auto-upgrade kicked off). All early-return paths return false.
  • src/index.ts — when checkVersion() returns false (and the user isn't already running sf migrate), show the new migration banner. Still skipped under --json.
  • src/lib/migrate.ts — new module exporting:
    • showMigrateBanner() — cyan boxen banner copy matching the existing upgrade-banner shape (short status, blank line, action, docs link).
    • handleMigrate() / registerMigrate()sf migrate fetches https://cli.sfcompute.com and pipes it to bash, mirroring handleUpgrade()'s pattern but with stdio inherited so users see the install progress live.

Banner copy

A new sf is here.

We're moving to a Rust CLI with new commands like
'sf availability', 'sf capacities', and 'sf orders'.

Run 'sf migrate' to install it. Your current sf will
be moved to 'sf-old' so you can keep using it.

Docs: https://docs.sfcompute.com/preview/guides/migrating-from-nodes

Sticks to the legacy banner's shape (lead with the news, blank line, action, link). Cyan rather than yellow to distinguish from urgency warnings — yellow is reserved for "please upgrade" / app-warning banners. Mentions the three headline commands from the preview quick-start and the sf-old fallback behavior baked into the new install script.

Testing

  • bun run check — passes
  • bun run lint — passes (no new warnings; pre-existing warnings unchanged)
  • bun run test — 9 passed
  • Smoke ran bun run dev --help and confirmed the banner renders correctly

Open in Indent Slack Thread
Tag @indent to continue the conversation here.

Show a cyan migration banner when the upgrade banner isn't being shown
to nudge users toward the new Rust-based sf CLI, and add a `sf migrate`
command that runs the new install script.

Generated with [Indent](https://indent.com)
Co-Authored-By: Indent <noreply@indent.com>
@indent
Copy link
Copy Markdown
Contributor

indent Bot commented May 21, 2026

PR Summary

Introduces a nudge toward a new Rust-based sf CLI by adding a sf migrate command (which downloads https://cli.sfcompute.com and pipes it into bash) and a recurring cyan banner shown when no upgrade banner is printed. checkVersion() is refactored to return a boolean so the caller can decide whether to print the migrate banner. The follow-up commit hardens both surfaces based on review feedback.

  • Refactored checkVersion() to Promise<boolean> (returns true when an upgrade banner or auto-upgrade ran) and updated every early-return path accordingly.
  • Added src/lib/migrate.ts with showMigrateBanner, handleMigrate, and registerMigrate; runInstallScript now uses a Promise.race over close/error with a try/catch around stdin.write, so missing/non-executable bash surfaces as a clean failure instead of an unhandled crash.
  • Gated the migrate banner in src/index.ts on process.argv[2] (tighter scoping), excluded both migrate and upgrade subcommands, and added an SF_CLI_DISABLE_MIGRATE_BANNER opt-out which is also surfaced inside the banner text.
  • Registered the new migrate command on the Commander program.

Issues

All clear! No issues remaining. 🎉

4 issues already resolved
  • Migrate banner prints during sf upgrade: checkVersion returns false early when args[0] === "upgrade", and the gate in index.ts only excludes migrate, so users running sf upgrade see the cyan "switch to the Rust CLI" banner above their upgrade output — the opposite of what the inline comment promises. (fixed by commit 8f91f5f)
  • spawn("bash", [], ...) in handleMigrate has no error listener — if bash is missing or non-executable (ENOENT/EACCES) the child emits an unhandled error event and crashes the CLI instead of returning a clean failure from runInstallScript. (fixed by commit 8f91f5f)
  • process.argv.slice(2).includes("migrate") matches the string migrate anywhere in argv (e.g. as a flag value or positional arg of another command), and diverges from the args[0] === "upgrade" pattern used a few lines away in checkVersion.ts. Use process.argv[2] === "migrate" for consistency and tighter scoping. (fixed by commit 8f91f5f)
  • No opt-out for the migrate banner: it prints on essentially every sf invocation forever, with no env var (compare SF_CLI_DISABLE_AUTO_UPGRADE in checkVersion.ts) and no cooldown like the 1h version cache. Power users running sf in scripts/shells will get spammed with no way to silence it. (fixed by commit 8f91f5f)

CI Checks

All CI checks passed on commit dd58923.

@sigmachirality sigmachirality added the indent label May 21, 2026 — with indent
@capy-ai
Copy link
Copy Markdown

capy-ai Bot commented May 21, 2026

Capy auto-review is paused for this organization because the monthly auto-review limit has been reached. Increase the limit or turn it off in billing settings to resume automatic reviews.

Comment thread src/index.ts Outdated
Comment thread src/lib/migrate.ts
sigmachirality and others added 3 commits May 21, 2026 22:13
- Skip migrate banner when running `sf upgrade` (was showing above
  upgrade output because checkVersion returns false early for it)
- Add SF_CLI_DISABLE_MIGRATE_BANNER opt-out, surfaced in the banner
- Use process.argv[2] === "migrate" for tighter scoping, matching
  the existing pattern in checkVersion.ts
- Handle spawn errors in handleMigrate so ENOENT/EACCES on bash
  surface as a clean failure instead of crashing the CLI

Generated with [Indent](https://indent.com)
Co-Authored-By: Indent <noreply@indent.com>
Lead with the Rust rewrite and new commands, then surface the
reselling story (the most important reason to migrate, per the
April 7 changelog) before the action and fallback text.

Generated with [Indent](https://indent.com)
Co-Authored-By: Indent <noreply@indent.com>
Per DTao.

Generated with [Indent](https://indent.com)
Co-Authored-By: Indent <noreply@indent.com>
@sigmachirality sigmachirality requested review from Sladuca and joshi4 May 22, 2026 03:19
Copy link
Copy Markdown
Contributor

@joshi4 joshi4 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

you can consider the alternative banner copy I suggested or ship as is, I leave that up to you.

Comment thread src/lib/migrate.ts
"https://docs.sfcompute.com/preview/guides/migrating-from-nodes";

export function showMigrateBanner() {
const message = `We've rewritten sf in Rust — faster, with new commands
Copy link
Copy Markdown
Contributor

@joshi4 joshi4 May 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is the first time some one is seeing this:
- sf capacities etc doesn't mean anything to them.
- rewritten in rust also doesn't entice them to migrate.

Suggested copy below. Tried to highlight better compute utilization/planning and reselling. If that piques their curiosity then can look at our docs.

A new sf is here.

Intuitive tools to plan, buy, and utilize compute.

Resell unused compute back on our orderbook and earn credits.

Opt in to get early access.

Run 'sf migrate'...

Docs: <link to preview docs>

Alternative Resell line:

Save upto 20% by reselling compute back on our orderbook and earn credits. Source: https://sfcompute.slack.com/archives/C09UJ3K6T4P/p1779323745810779

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants