Changelog
Release history for the sfp CLI — what changed in each version.
The sfp CLI carries its own version line, separate from sfp server's. Releases are published to npm as @flxbl-io/sfp and in the sfp docker images; see Install sfp. Under codev the CLI runs on the server, at the server's release.
Only releases that change the CLI are listed. A version absent from this page shipped no CLI-facing change.
September 2026
v52.19.0 — September 16, 2026
sfp server updatelogs the Hatchet worker-assignment commands it runs over SSH against a remote host, and their output, at debug level rather than info. A command that exits non-zero is still reported at error level.sfp server updatenames the worker-assignment pause before it runs, and on resume reports how many workers had their assignments restored and how many registrations the restart replaced. That report is printed whether the update finishes or fails.
v52.18.2 — September 15, 2026
sfp server callback post --context-idtakes the UUID of a callback context held on the server, in place of the inline JSON on--context. The two flags are mutually exclusive and exactly one is required; the command reads the context from the server with the server URL and application token before it posts.sfp server callback postfails before posting on a--context-idthat is not a UUID, a--contextthat is not valid JSON, a context that is not a JSON object, and a context whoseusername,accessLevel,targetOrg,taskId,taskTypeormessageis not a string.
v52.18.0 — September 15, 2026
- A package install that composes partial CustomObject metadata — layout assignments from
mutators/layout-assignments.yml, and the search-layouts contribution that augments them — carries the target org's object settings into that partial: the supported feature flags,description,gender,startsWith, each targeted record type'sdescription, and the name field'strackHistoryandtrackFeedHistory. A CustomObject deployment resetsallowInChatterGroups,enableActivitiesandenableReportsand clearsdescription,genderandstartsWithwhen they are omitted, so the composed partial previously reset them on install. - That composition stops before deployment when the org's CustomObject metadata is incomplete — a missing label or
nameField, an AutoNumber name field with nodisplayFormat, a value that is not a valid boolean, or anenableBulkApi/enableSharing/enableStreamingApigroup that is inconsistent — instead of composing a partial that would reset a property. - Each setting is written only when the Metadata API version supports it. The version is the one the install deploys with, falling back to the package's
apiVersionand then to the component set's. sfp validate orgruns its AI error analysis before it publishes the validation result, so the analysis reaches the published result and its markdown as well as the CI check. It previously ran only while the CI check was being created.sfp validate orgcancels the AI error analysis at its timeout — three minutes, unlesserrorAnalysis.timeoutin the AI configuration sets another, in milliseconds — and aborts the agent session rather than leaving the request in flight. A transient failure is retried up to three attempts, after 5 and 10 seconds, within that same deadline.- The validation markdown records
AI error analysis unavailable: <reason>when the analysis produces no insight, where the reason isno credentials,timed out,unparseable response,attempts exhaustedoranalysis failed. sfp validate orgreads its AI configuration from the validation worktree —config/ai-assist.yaml, then the.ymlspelling, thenconfig/ai-architecture.yamland.yml— rather than from the directory the command was started in. The analysis is skipped when the run failed because no changes were detected in the packages to be built, and runs whenever--opencode-serveris set.sfp releasecandidate unbundleremoves the file when a conflict has no copy of it on the side--conflict-strategyselects, instead of resolving markers in a file that side deleted.sfp releasecandidate unbundlefails when it cannot resolve the new SHA of a cherry-picked commit. It previously logged a warning and continued, leaving the deployment step lineage incomplete.sfp releasecandidate unbundle-analyzecounts only re-applied commits in the kept-commit total it prints and returns. A commit that turned out empty after conflict resolution, and was skipped, is no longer counted.sfp auth loginandsfp server auth loginserve branded sign-in result pages on the CLI's loopback receiver. The failure page escapes the detail returned by the authorization server and namessfp auth loginas the command to run again.sfp publishincludes the repository and an ISO 8601 timestamp in the webhook events it triggers on sfp server. The repository is read fromSFP_REPOSITORY,GITHUB_REPOSITORYorGITLAB_REPOSITORY, in that order.
v52.17.0 — September 11, 2026
sfp publish --pushgittagpushes the tags for all published packages in a singlegit push, instead of one push per package. A transient failure — a dropped connection, an unresolved host, an HTTP 5xx — is retried three times, after 2, 5 and 15 seconds. An authentication, permission, protected-tag or ruleset rejection is not retried.sfp publishcompletes when the tag push does not, instead of failing the run. It lists the tags that still need pushing and thegit push origin refs/tags/…command that pushes them, with remote URLs and credentials stripped from the reported error, and leaves the--gittaglimitand--gittagagecleanup for that retry.sfp releasecandidate unbundle --source-branchdefaults to the branch recorded on the release candidate, falling back tomainwhen the candidate records none. It previously always defaulted tomain. An explicit value still takes precedence.sfp releasecandidate unbundleremoves its temporary worktree when the run fails as well as when it succeeds, and raises a failure through the command's own error handling — so--jsonreports it — instead of exiting immediately.sfp releasecandidate unbundlereports how many manual deployment steps were re-anchored onto the rewritten branch and how many were flagged for review. The command fails when the server cannot record that anchor migration, after the branch has been pushed.
v52.16.1 — September 10, 2026
sfp server updatepauses Hatchet worker assignments before it drains, then waits only for workflows that occupy a worker slot. Queued tasks are no longer waited on; they stay pending and run once the workers return. The drain is checked again after the image pre-pull and the Caddy recreation, and the paused workers are restored when the update finishes or fails.sfp server updateaborts before it stops any service when the drain fails or the running-workflow count cannot be read. It previously logged a warning and continued with the update.--forcestill skips both the pause and the drain, and--drain-timeoutstill bounds the wait, in seconds, defaulting to 3600.sfp scratch deletecompletes without error when the Dev Hub holds no active scratch org record for the username. The lookup previously raisedNo ActiveScratchOrg found for username <username>, which the command reported as a missing org or a permissions failure.
v52.16.0 — September 8, 2026
sfp org login --server --default-devhubaccepts--repository(alias--repo) to authenticate with the DevHub selected for that project, and fails when the server resolves the DevHub from anywhere else.sfp server org get-default-devhubtakes the same flag. Both name where the DevHub came from — the project's default DevHub, a legacy project registration, or the tenant default.sfp scratch loginwithout--devhub-usernamehas the server resolve the DevHub that owns the scratch org, instead of trying the tenant default DevHub and then each registered DevHub in turn.sfp sandbox loginwithout--production-usernamehas the server resolve the production org bound to the sandbox, instead of trying each registered production org in turn. A sandbox registered without a production connection logs in, and the output omits theProduction Orgline.sfp server pool monitornames the pool it is reconciling when it reads sandbox state from Salesforce, so the state covers that pool's own instances rather than every sandbox under the Dev Hub.sfp scratch deletefails when the Dev Hub rejects the deletion, instead of reporting success. A username with no active scratch org record in the Dev Hub is left alone.--passphraseon the SSH-based server commands —sfp server init,start,stop,status,logs,scaleandupdate— is passed to the SSH connection, so an encrypted--identity-filecan be used. The key is read when the flags are parsed and is no longer written into the lifecycle configuration that debug logging serialises.- Those same commands report an SFTP error raised while checking for a directory on the remote host, instead of treating the directory as absent.
v52.15.1 — September 7, 2026
sfp server updateandsfp server initcopy the Supabase schema to a remote host through a temporary archive that is extracted and then removed. Removing it now tolerates an archive that is already gone, so a repeated or concurrent run against the same tenant directory no longer fails after the extraction has succeeded.
v52.15.0 — September 4, 2026
sfp auth loginandsfp server auth loginsign in to flxbl cloud when no server URL is given, through the global auth service over OAuth 2.1 with PKCE and a loopback receiver bound to127.0.0.1.--sfp-server-urlno longer defaults tohttp://localhost:3029.sfp auth login --sfp-server-urlreads the server's/sfp/api/configbefore signing in: a server that reports itself as self-hosted routes the sign-in to the auth service it publishes, and an unreachable URL fails before a browser opens.--global-authand--no-global-authforce either service and no longer carry a default.sfp auth loginprints the sign-in URL before it opens a browser, so a session where no browser opens can still complete the sign-in. On the self-hosted path the browser is redirected to the server's hosted/auth/callbackpage, which shows ansfp1_login code to paste into the terminal when it cannot reach the CLI's loopback.sfp installandsfp releasegroup the output of each pre- and post-deployer and of thepreDeploymentandpostDeploymentscripts, and keep the component checksum skip pre-fetch lines inside the eligibility group.
v52.14.3 — September 2, 2026
sfp analyze --output-format githubrenders code-analyzer and architecture findings as a Markdown list — severity, rule, location and gate on the first line, the message on the next — instead of an HTML table.--output-format markdownkeeps its tables.sfp analyzeandsfp project version suggestpass the architecture and version-assist instructions to the AI as its system prompt, rather than prepending them to the pull request content being analysed. The architecture instructions return the empty JSON result the parser reads when there is no architecturally significant change, in place of a plain sentence.
v52.14.2 — September 2, 2026
sfp project preflightreports a repository with nosfdx-project.json, or one that cannot be parsed, as anot-configuredstatus with the cause listed under issues. Previously the read error aborted the run.
v52.14.1 — September 2, 2026
sfp cascade merge-assistno longer stops responding when the AI agent asks to access a directory outside the working tree. The request is answered instead of left pending.
v52.14.0 — September 1, 2026
sfp validategrounds its AI analysis of a failure. Commands it suggests are checked against the CLI's own command set, and browserforce settings are reported as org-UI settings rather than as CLI flags.- A package build reports a missing Package2 registration in the Dev Hub as that, instead of as a generic creation failure.
- Repository and npm-registry calls to sfp server report the server's own error message instead of a generic substitute.
August 2026
v52.12.0 — August 30, 2026
sfp analyzeruns the version-assist AI linter only when it is asked for.--version-assistruns it,--no-version-assistkeeps it off even when the project enables it, and with neither flag it runs only when the server project settings explicitly enable it.- A package install that fails on a transport error — a dropped connection, DNS, or TLS failure — names the underlying cause instead of reporting
fetch failed. sfp server scalesizes both Hatchet worker pools.--workerssets the general pool and sizes the long-running pool proportionally;--longrunning-workerssets the long-running pool explicitly;--drain-timeoutbounds the wait for in-flight work, and--forcescales down without draining.
v52.10.2 — August 27, 2026
sfp analyzereports a linter that was skipped as skipped, instead of reporting it as a pass.
v52.10.0 — August 26, 2026
sfp validate org --waittimesets the metadata deployment wait for each package, in minutes. Defaults to 120.sfp org drift analyze --max-ai-findingsskips the AI review when the mechanical candidate count exceeds the threshold. Defaults to 50.sfp apextests resumebounds result fetching, so a large-org run stores its results instead of abandoning them on a timeout.sfp server initcreates the admin team, so a newly initialised admin can manage the organisation.
v52.9.3 — August 25, 2026
- Dependency resolution ignores source package dependencies declared inside the same project.