Full Code of forcedotcom/cli for AI

main e6377d39c920 cached
50 files
864.9 KB
223.2k tokens
5 symbols
1 requests
Download .txt
Showing preview only (897K chars total). Download the full file or copy to clipboard to get everything.
Repository: forcedotcom/cli
Branch: main
Commit: e6377d39c920
Files: 50
Total size: 864.9 KB

Directory structure:
gitextract_q88b20da/

├── .git2gus/
│   └── config.json
├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── config.yml
│   ├── actions/
│   │   ├── new-issue/
│   │   │   ├── action.yml
│   │   │   ├── lib/
│   │   │   │   ├── index.d.ts
│   │   │   │   └── index.js
│   │   │   ├── src/
│   │   │   │   └── index.ts
│   │   │   └── tsconfig.json
│   │   └── validate-issue/
│   │       ├── action.yml
│   │       ├── lib/
│   │       │   ├── index.d.ts
│   │       │   ├── index.js
│   │       │   ├── nodeVersions.d.ts
│   │       │   └── nodeVersions.js
│   │       ├── messages/
│   │       │   ├── deprecated-cli.md
│   │       │   ├── old-cli.md
│   │       │   ├── provide-version.md
│   │       │   └── unsupported-node.md
│   │       ├── mock/
│   │       │   └── sample-context.json
│   │       ├── src/
│   │       │   ├── index.ts
│   │       │   └── nodeVersions.ts
│   │       └── tsconfig.json
│   └── workflows/
│       ├── closeStaleIssues.yml
│       ├── issue-updated.yml
│       └── new-label.yml
├── .gitignore
├── CHANGELOG.md
├── CODEOWNERS
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── README.md
├── SECURITY.md
├── package.json
├── releasenotes/
│   ├── README.md
│   ├── sf/
│   │   └── README.md
│   ├── sfdx/
│   │   ├── README.md
│   │   ├── v41.md
│   │   ├── v42.md
│   │   ├── v43.md
│   │   ├── v44.md
│   │   ├── v45.md
│   │   ├── v46.md
│   │   ├── v47.md
│   │   ├── v48.md
│   │   ├── v49.md
│   │   └── v50.md
│   ├── v49.md
│   └── v50.md
└── tsconfig.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .git2gus/config.json
================================================
{
  "productTag": "a1aB00000004Bx8IAE",
  "productTagLabels": { "area:afdx": "a1aEE000001vDZRYA2" },
  "defaultBuild": "offcore.tooling.66",
  "issueTypeLabels": {
    "feature": "USER STORY",
    "regression": "BUG P1",
    "bug": "BUG P3"
  },
  "hideWorkItemUrl": true,
  "statusWhenClosed": "CLOSED",
  "issueEpicMapping": {
    "BUG P1": "a3QB00000004yR1MAI",
    "BUG P3": "a3QB00000004yR1MAI"
  }
}


================================================
FILE: .gitattributes
================================================
.github/actions/**/lib/* linguist-generated=true


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: 'investigating'
assignees: ''

---
> **Note** 
> Before you submit your issue, make sure that:
> - You're using the latest version of Salesforce CLI.
> - You've searched both open and closed issues for related posts.
> - You've used the `doctor` command to diagnose common issues. 
> - You understand that GitHub Issues don't adhere to any agreement or SLA.
>   - If you require immediate assistance, use official channels such as Salesforce Customer Support.

### Summary
<!-- Short summary of what's going on or to provide context -->

### Steps To Reproduce

> **IMPORTANT**
> Provide a repository that's configured to reproduce the issue. If you are unable to provide a repo, please explain why not. The more info we have from the start, the faster we can resolve your issue.
> We may close your issue if you don't include proper instructions.
>
> - Generate a project with `sf project generate` or fork [dreamhouse-lwc](https://github.com/trailheadapps/dreamhouse-lwc).
> - Provide detailed step-by-step instructions on how to reproduce the issue.


> [!TIP]
> use `sf doctor --create-issue` to automatically fill the required information

### Expected result
<!-- Describe what should have happened -->

### Actual result
<!-- Describe what actually happened -->

### Additional information
<!-- Feel free to attach a screenshot -->

### System Information
<!-- Which shell or terminal are you using? (bash, zsh, powershell 7, cmd.exe, etc) -->
<!-- Paste the **full** output of the `sf version --verbose --json` command below -->

```json
PASTE_VERSION_OUTPUT_HERE
```


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
  - name: Salesforce DX Community
    url: https://success.salesforce.com/issues_index?tag=Salesforce%20DX
    about: Please ask and answer questions here.
  - name: Feature request
    url: https://github.com/forcedotcom/cli/discussions/new?category=ideas
    about: Feature requests should be opened as discussions


================================================
FILE: .github/actions/new-issue/action.yml
================================================
name: "Salesforce CLI Issues Bot"
description: "Preform automatic responses to github issues."
author: "Lisa Morgan"
inputs:
  repo-token:
    required: true
    description: "Token taken from secrets env var"
  message:
    required: true
    description: "Message to post in issue comment"
  label:
    required: false
    description: "A label the issue must contain to post the message"
runs:
  using: "node20"
  main: "lib/index.js"


================================================
FILE: .github/actions/new-issue/lib/index.d.ts
================================================
export {};


================================================
FILE: .github/actions/new-issue/lib/index.js
================================================
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/*
 * Copyright 2025, Salesforce, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
const core_1 = require("@actions/core");
const github_1 = require("@actions/github");
async function run() {
    try {
        // The issue request exists on payload when an issue is created
        // Sets action status to failed when issue does not exist on payload.
        const issue = github_1.context.payload.issue;
        if (!issue) {
            (0, core_1.setFailed)("github.context.payload.issue does not exist");
            return;
        }
        // Get input parameters.
        const token = (0, core_1.getInput)("repo-token");
        const message = (0, core_1.getInput)("message");
        const label = (0, core_1.getInput)("label");
        console.log("message: ", message);
        console.log("label: ", label);
        // Create a GitHub client.
        const octokit = (0, github_1.getOctokit)(token);
        // Get owner and repo from context
        const owner = github_1.context.repo.owner;
        const repo = github_1.context.repo.repo;
        // Create a comment on Issue
        // https://octokit.github.io/rest.js/#octokit-routes-issues-create-comment
        console.log("owner: " + owner);
        console.log("repo: " + repo);
        console.log("issue number: " + issue.number);
        const issueLabels = issue.labels;
        console.log("issue labels: ", issueLabels);
        // If label is passed in as an input, make sure it is on the issue before posting the message.
        // Otherwise, we want to post message on all issues regardless.
        if (label) {
            if (!issueLabels.find((issueLabel) => issueLabel.name === label)) {
                // We didn't find the label, so don't post on this issue.
                return;
            }
        }
        const { data: comments } = await octokit.rest.issues.listComments({
            owner,
            repo,
            issue_number: issue.number,
        });
        // If we have comments check out that this comment has not been previously commented
        if (comments.length) {
            if (comments.some((comment) => comment.body === message)) {
                console.log("Already commented");
                return;
            }
        }
        const response = await octokit.rest.issues.createComment({
            owner,
            repo,
            // eslint-disable-next-line @typescript-eslint/camelcase
            issue_number: issue.number,
            body: message,
        });
        console.log("created comment URL: " + response.data.html_url);
        (0, core_1.setOutput)("comment-url", response.data.html_url);
    }
    catch (err) {
        const error = err;
        (0, core_1.setFailed)(error.message);
    }
}
run();
//# sourceMappingURL=index.js.map

================================================
FILE: .github/actions/new-issue/src/index.ts
================================================
/*
 * Copyright 2025, Salesforce, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { getInput, setOutput, setFailed } from "@actions/core";
import { context, getOctokit } from "@actions/github";
import { Label } from "@octokit/webhooks-definitions/schema";

async function run() {
  try {
    // The issue request exists on payload when an issue is created
    // Sets action status to failed when issue does not exist on payload.
    const issue = context.payload.issue;
    if (!issue) {
      setFailed("github.context.payload.issue does not exist");
      return;
    }

    // Get input parameters.
    const token = getInput("repo-token");
    const message = getInput("message");
    const label = getInput("label");
    console.log("message: ", message);
    console.log("label: ", label);

    // Create a GitHub client.
    const octokit = getOctokit(token);

    // Get owner and repo from context
    const owner = context.repo.owner;
    const repo = context.repo.repo;

    // Create a comment on Issue
    // https://octokit.github.io/rest.js/#octokit-routes-issues-create-comment
    console.log("owner: " + owner);
    console.log("repo: " + repo);
    console.log("issue number: " + issue.number);

    const issueLabels = issue.labels as Label[];
    console.log("issue labels: ", issueLabels);

    // If label is passed in as an input, make sure it is on the issue before posting the message.
    // Otherwise, we want to post message on all issues regardless.
    if (label) {
      if (!issueLabels.find((issueLabel) => issueLabel.name === label)) {
        // We didn't find the label, so don't post on this issue.
        return;
      }
    }

    const { data: comments } = await octokit.rest.issues.listComments({
      owner,
      repo,
      issue_number: issue.number,
    });

    // If we have comments check out that this comment has not been previously commented
    if (comments.length) {
      if (comments.some((comment) => comment.body === message)) {
        console.log("Already commented");
        return;
      }
    }

    const response = await octokit.rest.issues.createComment({
      owner,
      repo,
      // eslint-disable-next-line @typescript-eslint/camelcase
      issue_number: issue.number,
      body: message,
    });
    console.log("created comment URL: " + response.data.html_url);

    setOutput("comment-url", response.data.html_url);
  } catch (err) {
    const error = err as Error;
    setFailed(error.message);
  }
}

run();


================================================
FILE: .github/actions/new-issue/tsconfig.json
================================================
{
  "extends": "@salesforce/dev-config/tsconfig-strict",
  "compilerOptions": {
    "outDir": "./lib"
  },
  "files": ["src/index.ts"]
}


================================================
FILE: .github/actions/validate-issue/action.yml
================================================
name: "Salesforce CLI Validate Issues"
description: "Validate information provided in an new Github issue."
author: "Eric Willhoit"
inputs:
  repo-token:
    required: true
    description: "Token taken from secrets env var"
runs:
  using: "node20"
  main: "lib/index.js"


================================================
FILE: .github/actions/validate-issue/lib/index.d.ts
================================================
export {};


================================================
FILE: .github/actions/validate-issue/lib/index.js
================================================
"use strict";
/*
 * Copyright 2025, Salesforce, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("@actions/core");
const github_1 = require("@actions/github");
const child_process_1 = require("child_process");
const semver = require("semver");
const fs_1 = require("fs");
const path = require("path");
const nodeVersions_1 = require("./nodeVersions");
async function run() {
    try {
        // Uncomment for local testing
        // const issue = JSON.parse(getFile("../mock/sample-context.json"));
        const issue = github_1.context.payload.issue;
        if (!issue) {
            (0, core_1.setFailed)("github.context.payload.issue does not exist");
            return;
        }
        // Temporary check to prevent this action from running on old issues
        // This will prevent noise on tickets already being investigated
        // This can be removed once the action has been running for a while
        const creationDate = new Date(issue.created_at);
        const cutoffDate = new Date("2023-06-14T00:00:00Z");
        if (creationDate < cutoffDate) {
            console.log("Issue was created before 6/14/2023, skipping");
            return;
        }
        // Create a GitHub client
        const token = (0, core_1.getInput)("repo-token");
        const octokit = (0, github_1.getOctokit)(token);
        // Get owner and repo from context
        // uncomment env var for local testing
        // process.env.GITHUB_REPOSITORY = "iowillhoit/gha-sandbox";
        const owner = github_1.context.repo.owner;
        const repo = github_1.context.repo.repo;
        const issue_number = issue.number;
        console.log("Issue URL:", issue.html_url);
        const { body } = issue;
        const { login: author } = issue.user;
        const { data: comments } = await getAllComments();
        // For version checks, we only care about comments from the author
        const authorComments = comments.filter((comment) => { var _a; return ((_a = comment === null || comment === void 0 ? void 0 : comment.user) === null || _a === void 0 ? void 0 : _a.login) === author; });
        // Build an array of the issue body and all of the comment bodies
        const bodies = [
            body,
            ...authorComments.map((comment) => comment.body),
        ].filter((body) => body !== undefined);
        const sfVersionRegex = /@salesforce\/cli\/([0-9]+.[0-9]+.[0-9]+(-[a-zA-Z0-9]+.[0-9]+)?)/g;
        const sfdxVersionRegex = /sfdx-cli\/([0-9]+.[0-9]+.[0-9]+(-[a-zA-Z0-9]+.[0-9]+)?)/g;
        const pluginVersionsRegex = /pluginVersions|Plugin Version:/;
        const nodeVersionRegex = /node-v(\d{2})\.\d+\.\d+/g;
        // Search all bodies and get an array of all versions found (first capture group)
        const sfVersions = bodies
            .map((body) => [...body.matchAll(sfVersionRegex)].map((match) => match[1]))
            .flat();
        const sfdxVersions = bodies
            .map((body) => [...body.matchAll(sfdxVersionRegex)].map((match) => match[1]))
            .flat();
        const nodeVersions = bodies
            .map((body) => [...body.matchAll(nodeVersionRegex)].map((match) => match[1]))
            .flat();
        // If we match pluginVersionRegex anywhere, we assume the user has provided the full --verbose output
        const pluginVersionsIncluded = bodies.some((body) => body === null || body === void 0 ? void 0 : body.match(pluginVersionsRegex));
        console.log("sfVersions", sfVersions);
        console.log("sfdxVersions", sfdxVersions);
        console.log("pluginVersionsIncluded", pluginVersionsIncluded);
        console.log("nodeVersions", nodeVersions);
        if ((sfVersions.length > 0 || sfdxVersions.length > 0) &&
            pluginVersionsIncluded) {
            // FUTURE TODO:
            // - Check for bundled plugins that are user installed (user) or linked (link)
            // - Could do a check to see if the users has a prerelease version installed
            let valid = true;
            if (sfVersions.length > 0) {
                const sfLatest = getLatestVersion("@salesforce/cli");
                const oneSatisfies = sfVersions.some((version) => semver.gte(version, sfLatest));
                if (!oneSatisfies) {
                    if (sfVersions.find((v) => v.startsWith("2."))) {
                        // If any sf versions provided start with 2.x, share update information
                        const oldSf = getFile("../messages/old-cli.md", {
                            THE_AUTHOR: author,
                            USER_CLI: "sf",
                            USER_VERSION: sfVersions.join("`, `"),
                            LATEST_VERSION: sfLatest,
                        });
                        postComment(oldSf);
                    }
                    else {
                        // If not, share deprecation information
                        const sfV1 = getFile("../messages/deprecated-cli.md", {
                            THE_AUTHOR: author,
                            OLD_CLI: "`sf` (v1)",
                        });
                        postComment(sfV1);
                    }
                    valid = false;
                }
            }
            if (sfdxVersions.find((v) => v.startsWith("7.")) &&
                !sfVersions.find((v) => v.startsWith("2."))) {
                const noOldSfdx = getFile("../messages/deprecated-cli.md", {
                    THE_AUTHOR: author,
                    OLD_CLI: "`sfdx` (v7)",
                });
                postComment(noOldSfdx);
                valid = false;
            }
            if (nodeVersions.length > 0) {
                if (!(await (0, nodeVersions_1.isAnyVersionValid)(new Date())(nodeVersions))) {
                    const nodeVersionMessage = getFile("../messages/unsupported-node.md", {
                        THE_AUTHOR: author,
                        NODE_VERSION: nodeVersions.join("`, `"),
                    });
                    postComment(nodeVersionMessage);
                    closeIssue();
                    valid = false;
                }
            }
            if (valid) {
                console.log("All information provided is valid!");
                removeLabel("more information required");
                addLabel("investigating");
                // This label will prevent the action from running again after version info has been confirmed
                // Otherwise, this action will continue to trigger after every weekly release as `latest` is bumped
                addLabel("validated");
            }
            else {
                console.log("Information provided is NOT valid");
                addLabel("more information required");
                removeLabel("investigating");
            }
        }
        else {
            console.log("Full version information was not provided");
            const message = getFile("../messages/provide-version.md", {
                THE_AUTHOR: issue.user.login,
            });
            postComment(message);
            addLabel("more information required");
            removeLabel("investigating");
        }
        // ---------
        // FUNCTIONS
        // ---------
        async function closeIssue() {
            return await octokit.rest.issues.update({
                owner,
                repo,
                issue_number,
                state: "closed",
            });
        }
        async function getAllComments() {
            return await octokit.rest.issues.listComments({
                owner,
                repo,
                issue_number,
            });
        }
        async function postComment(body) {
            // Check that this comment has not been previously commented
            if (comments.length) {
                if (comments.some((comment) => comment.body === body)) {
                    console.log("Already commented");
                    return;
                }
            }
            return await octokit.rest.issues.createComment({
                owner,
                repo,
                issue_number,
                body,
            });
        }
        async function addLabel(label) {
            await octokit.rest.issues.addLabels({
                owner,
                repo,
                issue_number,
                labels: [label],
            });
        }
        async function removeLabel(label) {
            try {
                await octokit.rest.issues.removeLabel({
                    owner,
                    repo,
                    issue_number,
                    name: label,
                });
            }
            catch (err) {
                const error = err;
                if (error.status === 404) {
                    console.log(`Cannot remove label '${label}' since it was not applied`);
                    return;
                }
                throw error;
            }
        }
        function getLatestVersion(plugin) {
            const distTags = (0, child_process_1.execSync)(`npm view ${plugin} dist-tags --json`).toString();
            return JSON.parse(distTags).latest;
        }
        function getFile(filename, replacements) {
            let contents = (0, fs_1.readFileSync)(path.join(__dirname, filename), "utf8");
            Object.entries(replacements || {}).map(([key, value]) => {
                contents = contents.replaceAll(key, value);
            });
            return contents;
        }
    }
    catch (err) {
        const error = err;
        (0, core_1.setFailed)(error.message);
    }
}
run();
//# sourceMappingURL=index.js.map

================================================
FILE: .github/actions/validate-issue/lib/nodeVersions.d.ts
================================================
export declare const isAnyVersionValid: (currentDate: Date) => (versions: string[]) => Promise<boolean>;


================================================
FILE: .github/actions/validate-issue/lib/nodeVersions.js
================================================
"use strict";
/*
 * Copyright 2025, Salesforce, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.isAnyVersionValid = void 0;
const isAnyVersionValid = (currentDate) => async (versions) => {
    const resp = (await (await fetch("https://raw.githubusercontent.com/nodejs/Release/main/schedule.json")).json());
    return versions
        .map((version) => `v${version}`)
        .some((formattedVersion) => formattedVersion in resp &&
        currentDate >= new Date(resp[formattedVersion].start) &&
        currentDate <= new Date(resp[formattedVersion].end));
};
exports.isAnyVersionValid = isAnyVersionValid;
//# sourceMappingURL=nodeVersions.js.map

================================================
FILE: .github/actions/validate-issue/messages/deprecated-cli.md
================================================
Hello @THE_AUTHOR :wave:

It looks like you're using an outdated version of Salesforce CLI. OLD_CLI is in "maintenance mode" as of July 12, 2023. We highly recommend you move from OLD_CLI to `sf` (v2) ASAP.

Moving to `sf` (v2) is easy and takes just two commands. Find all the information [here](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_move_to_sf_v2.htm).

After you move to the latest version of `sf` (v2), run your command again and provide the output of `sf version --verbose --json`.


================================================
FILE: .github/actions/validate-issue/messages/old-cli.md
================================================
Hello @THE_AUTHOR :wave: None of the versions of `USER_CLI` you shared match the latest release.

Shared: `USER_VERSION`
Latest: `LATEST_VERSION`

Update to the latest version of Salesforce CLI ([docs](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_update_cli.htm)) and confirm that you're still seeing your issue.
You can also try the `rc` and `nightly` releases! ([docs](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_install_cli_rc.htm))

After updating, share the full output of `USER_CLI version --verbose --json`


================================================
FILE: .github/actions/validate-issue/messages/provide-version.md
================================================
Hello @THE_AUTHOR :wave: It looks like you didn't include the full Salesforce CLI version information in your issue.
Please provide the output of `version --verbose --json` for the CLI you're using (`sf` or `sfdx`).

A few more things to check:

- Make sure you've provided detailed steps to reproduce your issue.
  - A repository that clearly demonstrates the bug is ideal.
- Make sure you've installed the latest version of Salesforce CLI. ([docs](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_update_cli.htm))
  - Better yet, try the `rc` or `nightly` versions. ([docs](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_install_cli_rc.htm))
- Try running the `doctor` command to diagnose common issues.
- Search GitHub for existing related issues.

Thank you!


================================================
FILE: .github/actions/validate-issue/messages/unsupported-node.md
================================================
Hello @THE_AUTHOR :wave: Your version of nodeJS (`NODE_VERSION`) is not supported.

We recommend using LTS and we support anything Node says is `Current`, `Active` and `Maintenance`.

See Node's [version status](https://nodejs.org/en/about/previous-releases).

This issue will be closed. If you're able to reproduce your issue on a supported node version, please open a new issue.


================================================
FILE: .github/actions/validate-issue/mock/sample-context.json
================================================
{
  "active_lock_reason": null,
  "assignee": null,
  "assignees": [],
  "author_association": "OWNER",
  "body": "@salesforce/cli/1.60.5 sfdx-cli/7.204.6 darwin-arm64 node-v18.15.0 pluginVersions",
  "closed_at": null,
  "comments": 0,
  "comments_url": "https://api.github.com/repos/iowillhoit/gha-sandbox/issues/16/comments",
  "created_at": "2023-06-06T21:03:32Z",
  "events_url": "https://api.github.com/repos/iowillhoit/gha-sandbox/issues/16/events",
  "html_url": "https://github.com/iowillhoit/gha-sandbox/issues/16",
  "id": 1744609461,
  "labels": [
    {
      "color": "FBCA04",
      "default": false,
      "description": "",
      "id": 5589614072,
      "name": "investigating",
      "node_id": "LA_kwDOI7bi188AAAABTSq9-A",
      "url": "https://api.github.com/repos/iowillhoit/gha-sandbox/labels/investigating"
    }
  ],
  "labels_url": "https://api.github.com/repos/iowillhoit/gha-sandbox/issues/16/labels{/name}",
  "locked": false,
  "milestone": null,
  "node_id": "I_kwDOI7bi185n_KC1",
  "number": 16,
  "performed_via_github_app": null,
  "reactions": {
    "+1": 0,
    "-1": 0,
    "confused": 0,
    "eyes": 0,
    "heart": 0,
    "hooray": 0,
    "laugh": 0,
    "rocket": 0,
    "total_count": 0,
    "url": "https://api.github.com/repos/iowillhoit/gha-sandbox/issues/16/reactions"
  },
  "repository_url": "https://api.github.com/repos/iowillhoit/gha-sandbox",
  "state": "open",
  "state_reason": null,
  "timeline_url": "https://api.github.com/repos/iowillhoit/gha-sandbox/issues/16/timeline",
  "title": "Test",
  "updated_at": "2023-06-06T21:49:50Z",
  "url": "https://api.github.com/repos/iowillhoit/gha-sandbox/issues/16",
  "user": {
    "avatar_url": "https://avatars.githubusercontent.com/u/1715111?v=4",
    "events_url": "https://api.github.com/users/iowillhoit/events{/privacy}",
    "followers_url": "https://api.github.com/users/iowillhoit/followers",
    "following_url": "https://api.github.com/users/iowillhoit/following{/other_user}",
    "gists_url": "https://api.github.com/users/iowillhoit/gists{/gist_id}",
    "gravatar_id": "",
    "html_url": "https://github.com/iowillhoit",
    "id": 1715111,
    "login": "iowillhoit",
    "node_id": "MDQ6VXNlcjE3MTUxMTE=",
    "organizations_url": "https://api.github.com/users/iowillhoit/orgs",
    "received_events_url": "https://api.github.com/users/iowillhoit/received_events",
    "repos_url": "https://api.github.com/users/iowillhoit/repos",
    "site_admin": false,
    "starred_url": "https://api.github.com/users/iowillhoit/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/iowillhoit/subscriptions",
    "type": "User",
    "url": "https://api.github.com/users/iowillhoit"
  }
}


================================================
FILE: .github/actions/validate-issue/src/index.ts
================================================
/*
 * Copyright 2025, Salesforce, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { getInput, setFailed } from "@actions/core";
import { context, getOctokit } from "@actions/github";
import { execSync } from "child_process";
import * as semver from "semver";
import { readFileSync } from "fs";
import * as path from "path";
import { isAnyVersionValid } from "./nodeVersions";

async function run() {
  try {
    // Uncomment for local testing
    // const issue = JSON.parse(getFile("../mock/sample-context.json"));
    const issue = context.payload.issue;

    if (!issue) {
      setFailed("github.context.payload.issue does not exist");
      return;
    }

    // Temporary check to prevent this action from running on old issues
    // This will prevent noise on tickets already being investigated
    // This can be removed once the action has been running for a while
    const creationDate = new Date(issue.created_at);
    const cutoffDate = new Date("2023-06-14T00:00:00Z");
    if (creationDate < cutoffDate) {
      console.log("Issue was created before 6/14/2023, skipping");
      return;
    }

    // Create a GitHub client
    const token = getInput("repo-token");
    const octokit = getOctokit(token);

    // Get owner and repo from context
    // uncomment env var for local testing
    // process.env.GITHUB_REPOSITORY = "iowillhoit/gha-sandbox";
    const owner = context.repo.owner;
    const repo = context.repo.repo;
    const issue_number = issue.number;

    console.log("Issue URL:", issue.html_url);

    const { body } = issue;
    const { login: author } = issue.user;
    const { data: comments } = await getAllComments();

    // For version checks, we only care about comments from the author
    const authorComments = comments.filter(
      (comment) => comment?.user?.login === author
    );
    // Build an array of the issue body and all of the comment bodies
    const bodies = [
      body,
      ...authorComments.map((comment) => comment.body),
    ].filter((body): body is string => body !== undefined);

    const sfVersionRegex = /@salesforce\/cli\/([0-9]+.[0-9]+.[0-9]+(-[a-zA-Z0-9]+.[0-9]+)?)/g;
    const sfdxVersionRegex = /sfdx-cli\/([0-9]+.[0-9]+.[0-9]+(-[a-zA-Z0-9]+.[0-9]+)?)/g;
    const pluginVersionsRegex = /pluginVersions|Plugin Version:/;
    const nodeVersionRegex = /node-v(\d{2})\.\d+\.\d+/g;

    // Search all bodies and get an array of all versions found (first capture group)
    const sfVersions = bodies
      .map((body) =>
        [...body.matchAll(sfVersionRegex)].map((match) => match[1])
      )
      .flat();
    const sfdxVersions = bodies
      .map((body) =>
        [...body.matchAll(sfdxVersionRegex)].map((match) => match[1])
      )
      .flat();
    const nodeVersions = bodies
      .map((body) =>
        [...body.matchAll(nodeVersionRegex)].map((match) => match[1])
      )
      .flat();
    // If we match pluginVersionRegex anywhere, we assume the user has provided the full --verbose output
    const pluginVersionsIncluded = bodies.some((body) =>
      body?.match(pluginVersionsRegex)
    );
    console.log("sfVersions", sfVersions);
    console.log("sfdxVersions", sfdxVersions);
    console.log("pluginVersionsIncluded", pluginVersionsIncluded);
    console.log("nodeVersions", nodeVersions);
    if (
      (sfVersions.length > 0 || sfdxVersions.length > 0) &&
      pluginVersionsIncluded
    ) {
      // FUTURE TODO:
      // - Check for bundled plugins that are user installed (user) or linked (link)
      // - Could do a check to see if the users has a prerelease version installed
      let valid = true;

      if (sfVersions.length > 0) {
        const sfLatest = getLatestVersion("@salesforce/cli");
        const oneSatisfies = sfVersions.some((version) =>
          semver.gte(version, sfLatest)
        );

        if (!oneSatisfies) {
          if (sfVersions.find((v) => v.startsWith("2."))) {
            // If any sf versions provided start with 2.x, share update information
            const oldSf = getFile("../messages/old-cli.md", {
              THE_AUTHOR: author,
              USER_CLI: "sf",
              USER_VERSION: sfVersions.join("`, `"),
              LATEST_VERSION: sfLatest,
            });
            postComment(oldSf);
          } else {
            // If not, share deprecation information
            const sfV1 = getFile("../messages/deprecated-cli.md", {
              THE_AUTHOR: author,
              OLD_CLI: "`sf` (v1)",
            });
            postComment(sfV1);
          }
          valid = false;
        }
      }
      if (
        sfdxVersions.find((v) => v.startsWith("7.")) &&
        !sfVersions.find((v) => v.startsWith("2."))
      ) {
        const noOldSfdx = getFile("../messages/deprecated-cli.md", {
          THE_AUTHOR: author,
          OLD_CLI: "`sfdx` (v7)",
        });
        postComment(noOldSfdx);
        valid = false;
      }
      if (nodeVersions.length > 0) {
        if (!(await isAnyVersionValid(new Date())(nodeVersions))) {
          const nodeVersionMessage = getFile(
            "../messages/unsupported-node.md",
            {
              THE_AUTHOR: author,
              NODE_VERSION: nodeVersions.join("`, `"),
            }
          );
          postComment(nodeVersionMessage);
          closeIssue();
          valid = false;
        }
      }

      if (valid) {
        console.log("All information provided is valid!");
        removeLabel("more information required");
        addLabel("investigating");
        // This label will prevent the action from running again after version info has been confirmed
        // Otherwise, this action will continue to trigger after every weekly release as `latest` is bumped
        addLabel("validated");
      } else {
        console.log("Information provided is NOT valid");
        addLabel("more information required");
        removeLabel("investigating");
      }
    } else {
      console.log("Full version information was not provided");
      const message = getFile("../messages/provide-version.md", {
        THE_AUTHOR: issue.user.login,
      });
      postComment(message);
      addLabel("more information required");
      removeLabel("investigating");
    }

    // ---------
    // FUNCTIONS
    // ---------

    async function closeIssue() {
      return await octokit.rest.issues.update({
        owner,
        repo,
        issue_number,
        state: "closed",
      });
    }
    async function getAllComments() {
      return await octokit.rest.issues.listComments({
        owner,
        repo,
        issue_number,
      });
    }

    async function postComment(body: string) {
      // Check that this comment has not been previously commented
      if (comments.length) {
        if (comments.some((comment) => comment.body === body)) {
          console.log("Already commented");
          return;
        }
      }

      return await octokit.rest.issues.createComment({
        owner,
        repo,
        issue_number,
        body,
      });
    }

    async function addLabel(label: string) {
      await octokit.rest.issues.addLabels({
        owner,
        repo,
        issue_number,
        labels: [label],
      });
    }

    async function removeLabel(label: string) {
      try {
        await octokit.rest.issues.removeLabel({
          owner,
          repo,
          issue_number,
          name: label,
        });
      } catch (err) {
        const error = err as Error & { status: number };
        if (error.status === 404) {
          console.log(
            `Cannot remove label '${label}' since it was not applied`
          );
          return;
        }
        throw error;
      }
    }

    function getLatestVersion(plugin: string) {
      const distTags = execSync(
        `npm view ${plugin} dist-tags --json`
      ).toString();
      return JSON.parse(distTags).latest;
    }

    function getFile(
      filename: string,
      replacements: { [key: string]: string } | undefined
    ) {
      let contents = readFileSync(path.join(__dirname, filename), "utf8");

      Object.entries(replacements || {}).map(([key, value]) => {
        contents = contents.replaceAll(key, value);
      });

      return contents;
    }
  } catch (err) {
    const error = err as Error;
    setFailed(error.message);
  }
}

run();


================================================
FILE: .github/actions/validate-issue/src/nodeVersions.ts
================================================
/*
 * Copyright 2025, Salesforce, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

type VersionInfo = {
  start: Date;
  end: Date;
};

export const isAnyVersionValid = (currentDate: Date) => async (
  versions: string[]
): Promise<boolean> => {
  const resp = (await ((
    await fetch(
      "https://raw.githubusercontent.com/nodejs/Release/main/schedule.json"
    )
  ).json() as unknown)) as Record<string, VersionInfo>;

  return versions
    .map((version) => `v${version}`)
    .some(
      (formattedVersion) =>
        formattedVersion in resp &&
        currentDate >= new Date(resp[formattedVersion].start) &&
        currentDate <= new Date(resp[formattedVersion].end)
    );
};


================================================
FILE: .github/actions/validate-issue/tsconfig.json
================================================
{
  "extends": "@salesforce/dev-config/tsconfig-strict",
  "compilerOptions": {
    "outDir": "./lib",
    "lib": ["ES2021"]
  },
  "files": ["src/index.ts"]
}


================================================
FILE: .github/workflows/closeStaleIssues.yml
================================================
name: Close Stale Issues
permissions:
  issues: write
on:
  workflow_dispatch:
  schedule:
    - cron: '30 1 * * *'

jobs:
  stale:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/stale@v7
        with:
          stale-issue-label: stale
          days-before-issue-stale: 7
          stale-issue-message: 'This issue has not received a response in 7 days. It will auto-close in 7 days unless a response is posted.'
          operations-per-run: 100
          exempt-issue-labels: announcement,bug,on hold,waiting for internal reply,feature
          any-of-labels: more information required


================================================
FILE: .github/workflows/issue-updated.yml
================================================
name: "validate-updated-issue"
on:
  issues:
    types: [edited]
  issue_comment:
    types: [created, edited]

jobs:
  validate-issue:
    # Has label: 'more information required'
    # Does NOT have labels:
    # - 'validated'
    # - 'investigating'
    # - 'feature'
    # - 'owned by another team'
    # - 'bug'
    if: contains(github.event.issue.labels.*.name, 'more information required') && !contains(github.event.issue.labels.*.name, 'validated') && !contains(github.event.issue.labels.*.name, 'investigating') && !contains(github.event.issue.labels.*.name, 'feature') && !contains(github.event.issue.labels.*.name, 'owned by another team') && !contains(github.event.issue.labels.*.name, 'bug')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3.0.0
      - uses: actions/setup-node@v4
        with:
          node-version: lts/*
      - name: Install dependencies
        run: yarn install
      - name: Validate issue
        id: validate-issue
        uses: ./.github/actions/validate-issue
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN}}


================================================
FILE: .github/workflows/new-label.yml
================================================
name: "new-label"
on: # any labels added to an issue
  issues:
    types: [labeled]

jobs:
  owned-by-other-team:
    if: ${{ github.event.label.name == 'owned by another team' && !contains(github.event.issue.labels.*.name, 'feature') }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3.0.0
      - uses: actions/setup-node@v4
        with:
          node-version: lts/*
      - name: Install dependencies
        run: yarn install
      - name: issue comment
        id: issue_comment
        uses: ./.github/actions/new-issue
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          label: "owned by another team"
          message: >
            We have determined that the issue you reported exists in code owned by another team that uses only the official support channels.
            To ensure that your issue is addressed, open an official [Salesforce customer support](https://help.salesforce.com/s/) ticket with a link to this issue.
            We encourage anyone experiencing this issue to do the same to increase the priority. We will keep this issue open for the community to collaborate on.
      - name: log action output
        run: echo ${{ steps.run_action.outputs.message }}
  new-issue:
    if: ${{ github.event.label.name == 'investigating' }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3.0.0
      - uses: actions/setup-node@v4
        with:
          node-version: lts/*
      - name: Install dependencies
        run: yarn install
      - name: issue comment
        id: issue_comment
        uses: ./.github/actions/new-issue
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          label: "investigating"
          message: >
            Thank you for filing this issue.  We appreciate your feedback and will review the issue as soon as possible.
            Remember, however, that GitHub isn't a mechanism for receiving support under any agreement or SLA.
            If you require immediate assistance, contact Salesforce Customer Support.
      - name: log action output
        run: echo ${{ steps.run_action.outputs.message }}
  validate-new-issue:
    if: ${{ github.event.label.name == 'investigating' }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3.0.0
      - uses: actions/setup-node@v4
        with:
          node-version: lts/*
      - name: Install dependencies
        run: yarn install
      - name: Validate issue
        id: validate-issue
        uses: ./.github/actions/validate-issue
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}
  new-feature:
    if: ${{ github.event.label.name == 'feature' && !contains(github.event.issue.labels.*.name, 'owned by another team') }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3.0.0
      - uses: actions/setup-node@v4
        with:
          node-version: lts/*
      - name: Install dependencies
        run: yarn install
      - name: issue comment
        id: issue_comment
        uses: ./.github/actions/new-issue
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          label: "feature"
          message: >
            Thank you for filing this feature request. We appreciate your feedback and will review the feature at our next grooming or sprint planning session. We prioritize feature requests with more upvotes and comments.
      - name: log action output
        run: echo ${{ steps.run_action.outputs.message }}
  new-feature-on-another-team:
    if: >-
      (github.event.label.name == 'feature' || github.event.label.name == 'owned by another team')
      &&
      (contains(github.event.issue.labels.*.name, 'feature') && contains(github.event.issue.labels.*.name, 'owned by another team'))
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3.0.0
      - uses: actions/setup-node@v4
        with:
          node-version: lts/*
      - name: Install dependencies
        run: yarn install
      - name: issue comment
        id: issue_comment
        uses: ./.github/actions/new-issue
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          message: >
            Thank you for filing this feature request. However, we've determined that the functionality you've requested must be completed by another team. Please submit your request to the [Salesforce IdeaExchange](https://trailblazer.salesforce.com/ideaSearch). Then post a link to the request in this issue so that others can upvote your idea.
      - name: log action output
        run: echo ${{ steps.run_action.outputs.message }}


================================================
FILE: .gitignore
================================================
# Dependency directory
node_modules

# Rest pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Optional npm cache directory
.npm

# dotenv environment variables file
.env
.env.test

# OS metadata
.DS_Store
Thumbs.db

# Ignore built ts files
__tests__/runner/*

package-lock.json
/.idea


================================================
FILE: CHANGELOG.md
================================================
Changelog can be found here: https://github.com/forcedotcom/cli/blob/main/releasenotes/README.md


================================================
FILE: CODEOWNERS
================================================
# Technical writers will be added as reviewers on markdown changes.
*.md @forcedotcom/cli-docs

# Comment line immediately above ownership line is reserved for related other information. Please be careful while editing.
#ECCN:Open Source
#GUSINFO:Platform CLI,Platform CLI

================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Salesforce Open Source Community Code of Conduct

## About the Code of Conduct

Equality is a core value at Salesforce. We believe a diverse and inclusive
community fosters innovation and creativity, and are committed to building a
culture where everyone feels included.

Salesforce open-source projects are committed to providing a friendly, safe, and
welcoming environment for all, regardless of gender identity and expression,
sexual orientation, disability, physical appearance, body size, ethnicity, nationality, 
race, age, religion, level of experience, education, socioeconomic status, or 
other similar personal characteristics.

The goal of this code of conduct is to specify a baseline standard of behavior so
that people with different social values and communication styles can work
together effectively, productively, and respectfully in our open source community.
It also establishes a mechanism for reporting issues and resolving conflicts.

All questions and reports of abusive, harassing, or otherwise unacceptable behavior
in a Salesforce open-source project may be reported by contacting the Salesforce
Open Source Conduct Committee at ossconduct@salesforce.com.

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of gender 
identity and expression, sexual orientation, disability, physical appearance, 
body size, ethnicity, nationality, race, age, religion, level of experience, education, 
socioeconomic status, or other similar personal characteristics.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy toward other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Personal attacks, insulting/derogatory comments, or trolling
* Public or private harassment
* Publishing, or threatening to publish, others' private information—such as
a physical or electronic address—without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
* Advocating for or encouraging any of the above behaviors

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned with this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project email
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the Salesforce Open Source Conduct Committee 
at ossconduct@salesforce.com. All complaints will be reviewed and investigated 
and will result in a response that is deemed necessary and appropriate to the 
circumstances. The committee is obligated to maintain confidentiality with 
regard to the reporter of an incident. Further details of specific enforcement 
policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership and the Salesforce Open Source Conduct 
Committee.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][contributor-covenant-home],
version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html. 
It includes adaptions and additions from [Go Community Code of Conduct][golang-coc], 
[CNCF Code of Conduct][cncf-coc], and [Microsoft Open Source Code of Conduct][microsoft-coc].

This Code of Conduct is licensed under the [Creative Commons Attribution 3.0 License][cc-by-3-us].

[contributor-covenant-home]: https://www.contributor-covenant.org (https://www.contributor-covenant.org/)
[golang-coc]: https://golang.org/conduct
[cncf-coc]: https://github.com/cncf/foundation/blob/master/code-of-conduct.md
[microsoft-coc]: https://opensource.microsoft.com/codeofconduct/
[cc-by-3-us]: https://creativecommons.org/licenses/by/3.0/us/


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to the Salesforce CLI
Welcome, and thank you for your interest in contributing to the Salesforce CLI!

There are multiple ways you can contribute. Before you get started, please review our [Code of Conduct](CODE_OF_CONDUCT.md) to help us keep our OSS projects a safe and welcoming environment.

### Report an issue
Did you find a bug? First, make sure the bug wasn't already reported by searching on the `issues` section: https://github.com/forcedotcom/cli/issues.
If you cannot find a related issue, then open a new one and follow the bug template. Providing a minimal reproduction is highly encouraged as these help us to quickly identify the root cause of the issue.

### Security
Please report any security issue to security@salesforce.com as soon as it is discovered.

### Pull requests
We accept pull requests for bug fixes and feature requests for any issues labeled with [`help wanted`](https://github.com/forcedotcom/cli/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22).
You can leave a comment in the issue you are interested to work on and we will assign it to you.

We work in branches off of `main`, to create a PR you should:

1. Fork the plugin/library repo you want to contribute to.
2. Create a new branch: `git checkout -b fix-bug`
3. Make your changes and ensure all tests pass.
4. [Create a pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request)

#### Note:
We use conventional commits in all of our repos. Our CI/CD pipeline relies on each commit type to decide whether or not to publish a new release and we enforce this using a git hook to run `commitlint`, make sure to folow this convention, otherwise `commitlint` will not allow you to commit your change.

Conventional Commits: https://www.conventionalcommits.org/en/v1.0.0/#summary

`commitlint`: https://github.com/conventional-changelog/commitlint/#what-is-commitlint

## CLA
External contributors will be required to sign a Contributor's License Agreement. You can do so by going to: https://cla.salesforce.com/sign-cla.

## Building the project

Prerequisites:
* [Node.js](https://nodejs.org/) (recommended: latest active LTS release)
* [Yarn v1](https://classic.yarnpkg.com/) (`npm install --global yarn`)

1. Clone the repo: 
    * `sf`: `git clone https://github.com/salesforcecli/cli.git`
2. Install dependencies: `yarn install`
3. Build the project: `yarn build`
4. Run the CLI using the `bin/run` executable as:
    * macOS/linux: `bin/run`
    * Windows: `bin\run.cmd`


## Project structure

The `sf` CLI is built from plugins, some are bundled and come installed with the CLI, others are installed on demand.

The bundled plugins are:

* [plugin-apex](https://github.com/salesforcecli/plugin-apex/)
* [plugin-auth](https://github.com/salesforcecli/plugin-auth/)
* [plugin-data](https://github.com/salesforcecli/plugin-data)
* [deploy-retrieve](https://github.com/salesforcecli/plugin-deploy-retrieve)
* [plugin-info](https://github.com/salesforcecli/plugin-info)
* [plugin-limits](https://github.com/salesforcecli/plugin-limits)
* [plugin-login](https://github.com/salesforcecli/plugin-login)
* [plugin-org](https://github.com/salesforcecli/plugin-org)
* [plugin-schema](https://github.com/salesforcecli/plugin-schema)
* [plugin-settings](https://github.com/salesforcecli/plugin-settings)
* [plugin-sobject](https://github.com/salesforcecli/plugin-sobject)
* [plugin-telemetry](https://github.com/salesforcecli/plugin-telemetry)
* [plugin-templates](https://github.com/salesforcecli/plugin-templates)
* [plugin-trust](https://github.com/salesforcecli/plugin-trust)
* [plugin-user](https://github.com/salesforcecli/plugin-user)

The just-in-time plugins that are installed the first time you run a command are:

* [plugin-custom-metadata](https://github.com/saleforcecli/plugin-custom-metadata)
* [plugin-community](https://github.com/saleforcecli/plugin-community)
* [plugin-dev](https://github.com/saleforcecli/plugin-dev)
* [plugin-env](https://github.com/saleforcecli/plugin-env)
* [plugin-functions](https://github.com/salesforcecli/plugin-functions)
* [plugin-packaging](https://github.com/salesforcecli/plugin-packaging)
* [plugin-signups](https://github.com/saleforcecli/plugin-signups)
* [sfdx-plugin-lwc-test](https://github.com/salesforcecli/sfdx-plugin-lwc-test)
* [sfdx-scanner](https://github.com/salesforcecli/sfdx-scanner)

For an up-to-date list of CLI plugins and libraries, see: https://github.com/salesforcecli/status

## Architecture

For more information on how the `sf` CLI is organized, see https://github.com/salesforcecli/cli/blob/main/ARCHITECTURE.md


================================================
FILE: LICENSE.txt
================================================
Apache License Version 2.0

Copyright (c) 2025 Salesforce, Inc.
All rights reserved.

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "{}"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright {yyyy} {name of copyright owner}

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.



================================================
FILE: README.md
================================================
# Description

This is an issue-only repository for Salesforce CLI. We monitor this repo for feedback from the community and we post proposals for CLI changes we're working on to see what you think. We also store the weekly release notes here.

If you have a feature or enhancement request for Salesforce CLI, first review the [existing discussions](https://github.com/forcedotcom/cli/discussions) to see if someone has already requested it. If you don't see your feature or enhancement, click the **New discussion** button to create a new request. 

Similarly, if you've encountered a bug with Salesforce CLI, check out the [existing issues](https://github.com/forcedotcom/cli/issues) to see if it's already been reported. If you don’t see your bug listed, click the **New issue** button to create one. 

NOTICE: GitHub isn't a mechanism for receiving support under any agreement or SLA. If you require immediate assistance, use official Salesforce customer support channels.

# Contributing

If you are interested in contributing, take a look at the [CONTRIBUTING](.github/CONTRIBUTING.md) guide.

When contributing to Github Actions, modify the `.github/actions/**/src` files. A pre-commit hook will build and commit the compiled `lib` files. When adding a new action, add the path to the `references` in the base `tsconfig.json` file.

# A note on CLI Unification

On July 2023 we [announced the General Availability (GA)](https://developer.salesforce.com/blogs/2023/07/salesforce-cli-sf-v2-is-here) of `sf` (v2), which is the culmination of our CLI unification efforts, which started back in 2021 with [`sf` (v1)](https://developer.salesforce.com/blogs/2021/06/announcing-salesforce-cli-unification). `sf` (v2) is smart enough to understand both `sfdx` and `sf` commands, and due to its smaller size, it's faster to install and update. For more information see:

* [Move from `sfdx` (v7) to `sf` (v2)](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_move_to_sf_v2.htm) 
* [Migrate `sfdx`-Style Commands to the New `sf`-Style](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_migrate.htm)

# Salesforce DX and CLI Documentation 

* _[Release Notes](./releasenotes/README.md)_ - Read about the new and changed features in recent weekly updates to Salesforce CLI. 
* _[Salesforce CLI Setup Guide](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_intro.htm)_ - How to install, update, and configure Salesforce CLI. 
* _[Salesforce DX Developer Guide](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_intro.htm)_ - Step-by-step guide on how to use the Salesforce DX tools.
* _[Salesforce CLI Command Reference](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference.htm)_ - Complete reference documentation for all Salesforce CLI commands.
* _[sf Plugin Developer Guide](https://github.com/salesforcecli/cli/wiki/Quick-Introduction-to-Developing-sf-Plugins)_ - Learn how to create your own custom plugin.
* [Build Apps Together with Package Development](https://trailhead.salesforce.com/en/content/learn/trails/sfdx_get_started) - Step-by-step Trailhead trail of tutorials for the Salesforce DX tools.
* [Salesforce Developers Blog](https://developer.salesforce.com/blogs/) 

# The up-to-date list of CLI [Repositories](https://github.com/salesforcecli/status) 


================================================
FILE: SECURITY.md
================================================
## Security

Please report any security issue to [security@salesforce.com](mailto:security@salesforce.com)
as soon as it is discovered. This library limits its runtime dependencies in
order to reduce the total cost of ownership as much as can be, but all consumers
should remain vigilant and have their security stakeholders review all third-party
products (3PP) like this one and their dependencies.


================================================
FILE: package.json
================================================
{
  "name": "cli",
  "version": "1.0.0",
  "description": "Issues Only repository for the community to submit feedback, raise issues and propose enhancements to the Salesforce CLI.",
  "scripts": {
    "build": "tsc --build"
  },
  "husky": {
    "hooks": {
      "pre-commit": "yarn build && git add .github/actions/**/lib"
    }
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/forcedotcom/cli.git"
  },
  "author": "Lisa Morgan",
  "dependencies": {
    "@actions/core": "^1.10.0",
    "@actions/github": "^5.1.1",
    "semver": "^7.5.2"
  },
  "devDependencies": {
    "@octokit/webhooks-definitions": "^3.67.3",
    "@salesforce/dev-config": "^2.0.0",
    "@types/node": "^20.11.17",
    "@types/semver": "^7.5.0",
    "husky": "^4.3.0",
    "prettier": "^1.19.1",
    "typescript": "4.9.5"
  },
  "bugs": {
    "url": "https://github.com/forcedotcom/cli/issues"
  },
  "homepage": "https://github.com/forcedotcom/cli#readme",
  "license": "Apache-2.0"
}


================================================
FILE: releasenotes/README.md
================================================
# Salesforce CLI Release Notes

Here are the new and changed features in recent updates of Salesforce CLI.

We publish a new stable version of Salesforce CLI on Wednesdays. At the same time we also publish a release candidate that contains changes that will likely be in next week's stable release. We also publish nightly releases every night. Run `sf version` to display the version installed on your computer. 

> **IMPORTANT**: Are you still using `sfdx` (v7)?  If so, we recommend that you move to `sf` (v2). It's easy: simply uninstall `sfdx` and then install `sf`. See the new [Move from `sfdx` (v7) to `sf` (v2)](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_move_to_sf_v2.htm) section of the Setup Guide for details, including how to update your continuous integration (CI) scripts. We've also updated the entire Setup Guide to assume you're using `sf` (v2) and the `sf`-style CLI commands and configuration. **`sfdx` (v7) will receive no updates.**

If you installed Salesforce CLI using the installers or TAR files, run `sf update stable` to update to the latest available stable version. Run `sf update stable-rc` to update to this week's release candidate and `sf update nightly` to update to the most recent nightly. 

If you installed Salesforce CLI using `npm`, run `npm install @salesforce/cli@latest --global` to install the latest stable version. Run `npm install @salesforce/cli@latest-rc --global` to install the release candidate and `npm install @salesforce/cli@nightly --global` to install the recent nightly.

For all installation methods, see [this document](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_install_cli.htm#sfdx_setup_install_cli_olderversions) to install an old Salesforce CLI release.

If you use [autocomplete](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_dev_cli_autocomplete.htm), run `sf autocomplete --refresh-cache` after you update Salesforce CLI to ensure that autocomplete works correctly on any new commands.

Report and read about issues [here](https://github.com/forcedotcom/cli/issues). Join the discussion about new features we're considering [here](https://github.com/forcedotcom/cli/discussions). 

Looking for the release notes for previous Salesforce CLI releases?  See [`sfdx` (v7)](./sfdx/README.md) and [`sf` (v1)](./sf/README.md).

Additional documentation:

* [Salesforce CLI Command Reference](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference.htm)
* [Salesforce DX Developer Guide](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_intro.htm)
* [Salesforce CLI Plugin Developer Guide](https://github.com/salesforcecli/cli/wiki/Quick-Introduction-to-Developing-sf-Plugins)
* [Salesforce CLI Setup Guide](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_intro.htm)

## 2.130.8 (April 8, 2026) [stable-rc]

These changes are in the Salesforce CLI release candidate. We plan to include these changes in next week's official release. This list isn't final and is subject to change.

------------

* NEW: We standardized the error codes that `agent` commands throw when they run into issues.  For example, both `agent publish authoring-bundle` and `agent validate authoring-bundle` now throw the same error code if they run into Agent Script compilation errors.  These are the error codes that the `agent` commands might throw:

    |Error Code| Error Text|
    |--------|-------
	|`Succeeded (0)`|Preview session ended successfully and traces saved.|
    |`NotFound (2)`|Agent not found, or no preview session exists for this agent.|
    |`PreviewEndFailed (4)`|Failed to end the preview session.|
    |`SessionAmbiguous (5)`|Multiple preview sessions found; specify --session-id to choose one.|

   (plugin-agent PR [#378](https://github.com/salesforcecli/plugin-agent/pull/378))

* CHANGE: When running `agent preview start` to start a programmatic agent preview session using an agent's authoring bundle (`--authoring-bundle` flag), you're now required to specify either simulated or live mode.  Specify simulated mode with the new `--simulate-actions` flag; specify live actions with the existing `--use-live-actions` flag.  Previously, the programmatic agent preview ran in simulated mode by default; to use live mode you had to explicitly specify the `--use-live-actions` flag.

    Published agents, which you specify with the --api-name, always use live actions. (plugin-agent PR [#380](https://github.com/salesforcecli/plugin-agent/pull/380))

* FIX: If the `org assign permset` CLI command encounters multiple errors during a permission set assignment, we now correctly provide all the known details about the errors in the JSON output so you can better diagnose the problem. (GitHub Issue [#3511](https://github.com/forcedotcom/cli/issues/3511), plugin-user PR [#1398](https://github.com/salesforcecli/plugin-user/pull/1398))

* FIX: Salesforce DX projects now support these [metadata types](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json):

    * CnfgItemSourceDefinition (replaces CnfgMgmtCiSourceDef)
    * ExtlClntAppOauthSecuritySettings
    * UIBundle (replaces WebApplication) 

## 2.129.8 (April 1, 2026) [stable]

* NEW: Create a Salesforce DX project that includes a sample agent with the new `agent` template value of the `template generate project` command.  For example:

   ```bash
   sf template generate project --name my-agent-project --template agent
   ```
   The new `agent` template is also listed as an option when you create a project in VS Code with the **SFDX: Create Project** command.

   The generated Salesforce DX project contains a sample agent called `Local Info Agent` inside the `force-app/main/default/aiAuthoringBundles/Local_Info_Agent` authoring bundle. The agent could be embedded in a resort's web site to provide local weather updates, share information about local events, and help guests with facility hours. The agent demonstrates:

   - Three types of subagents (Invocable Apex, Prompt Template, and Flow).
   - Mutable variables.
   - Flow control with `available when`.
   - Deterministic branching with `if/else` in reasoning instructions.

    The DX project also includes other metadata that implement the sample agent, such as Apex classes, a flow, and a prompt template, as well as permission sets and permission set groups.  See the `README.md` file in the root directory of the new DX project for more info.
  
   (salesforcedx-templates PR [#753](https://github.com/forcedotcom/salesforcedx-templates/pull/753), plugin-templates PR [#874](https://github.com/salesforcecli/plugin-templates/pull/874))

* NEW: (Generally Available) The commands to preview an agent programmatically, without starting an interactive session, are now generally available. These commands are particularly useful when you want an agent to test your agent.

    - `agent preview start`:     Start a programmatic agent preview session.
    - `agent preview send`:      Send a message to an existing agent preview session.
    - `agent preview sessions`:  List all known programmatic agent preview sessions.
    - `agent preview end`:  End an existing programmatic agent preview session and get trace location.
  
     (plugin-agent PR [#367](https://github.com/salesforcecli/plugin-agent/pull/367))

* NEW: We added the [Agentforce DX VS Code Extension](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-agents) to this week's release of the Salesforce Extension Pack (v66.3), which is available from either the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode) or the [Open VSX Registry](https://open-vsx.org/extension/salesforce/salesforcedx-vscode).   This change means that if you're setting up Agentforce DX tools for the first time on VS Code, you only need to install the Salesforce extension pack, which includes all the things. Already set up your tools?  Then you don't need to do anything. 

    The Salesforce Extension Pack includes tools for developing on the Salesforce Platform. Use these tools to work with development orgs (scratch orgs, sandboxes, and Developer Edition orgs), Apex, Lightning web components, and SOQL. The extension pack also includes Agentforce Vibes, and now Agentforce DX.  (salesforcedx-vscode PR [#7003](https://github.com/forcedotcom/salesforcedx-vscode/pull/7003))

* NEW: Easily create the default Salesforce user that is used to run an agent in your org with the new `org create agent-user` CLI command.  You specify this user in the agent's Agent Script file using the `default_agent_user` parameter in the [`config` block](https://developer.salesforce.com/docs/ai/agentforce/guide/ascript-blocks.html#config-block).  

  By default, the command generates a user called `Agent User` with a globally unique username.  Use the `--first-name`, `--last-name`, and `--base-username` flags to change these default names. The command also assigns the required profiles and permission sets.  Run `sf org create agent-user --help` for more details. When the command completes, it displays a summary of what it did, including the new agent user's username and ID.

   This example creates an agent user with an auto-generated username but the custom name `Service Agent` in the org with alias `my-org`:

   ```bash
   sf org create agent-user --first-name Service --last-name Agent --target-org my-org
   ```
    (vscode-agents PR [#168](https://github.com/forcedotcom/vscode-agents/pull/168))
  
* NEW: When you activate an agent in VS Code with the **AFDX: Active Agent** command, you're now prompted for the version you want to activate.  (vscode-agents PR [#168](https://github.com/forcedotcom/vscode-agents/pull/168))

* NEW: Specify a custom directory into which the `agent generate template` command generates the `BotTemplate` and `GenAiPlannerBundle` files with the new `--output-dir` flag. If you don't specify this flag, then the files are generated in the default package directory. 

   This example generates an agent template of version 1 of the `My_Awesome_Agent` Bot metadata file into the `my-package` directory:

   ```bash
   sf agent generate template --agent-file force-app/main/default/bots/My_Awesome_Agent/My_Awesome_Agent.bot-meta.xml --agent-version 1 --source-org my-scratch-org --output-dir my-package
   ```
   
  (plugin-agent PR [#376](https://github.com/salesforcecli/plugin-agent/pull/376))

* NEW: (oclif only) Use the new `multiple: true` support of positional arg definitions to give your commands a type-safe way to accept a variable number of positional arguments.  See [Command Arguments](https://oclif.io/docs/args) for more info. 

    Thank you, [Espen Hovlandsdal](https://github.com/rexxars), for your contribution to oclif!  While Salesforce CLI avoids the usage of positional arguments and varargs, other non-Salesforce developers who build CLIs on oclif are sure to find this new feature useful.  (core PR [#1554](https://github.com/oclif/core/pull/1554))

* CHANGE: For increased security, we changed the behavior of `org generate password` so it always generates passwords of higher complexity.

    Specifically, if you pass the `--complexity` flag a value below 3, the command now ignores that value and instead generates a password of complexity 3, which means a password that includes only lower and upper case letters and numbers. The command also displays a message about this changed behavior.  Starting in Summer '26, the command will fail if you specify a complexity value less than 3. (plugin-user PR [#1389](https://github.com/salesforcecli/plugin-user/pull/1389), 

* FIX: We fixed [this issue](https://help.salesforce.com/s/issue?id=a02Ka00000ji2nu) with the `agent generate template` command caused by packaging local actions and topics. As a result of the fix, you can now correctly generate an agent template, and then package the template in a second-generation managed package, without going through the workaround.

    IMPORTANT: This fix added a new requirement when you run `agent generate template`: you must now use the new `--source-org` flag to specify the username or alias of the namespaced scratch org that contains the agent which the template is based on. For example, this command generates an agent template from version 1 of the `My_Awesome_Agent` Bot metadata file in your DX project; the agent that the new template is based on is in the org with alias "my-scratch-org":
  
   ```bash
   sf agent generate template --agent-file force-app/main/default/bots/My_Awesome_Agent/My_Awesome_Agent.bot-meta.xml --agent-version 1 --source-org my-scratch-org
    ```

   (plugin-agent PR [#376](https://github.com/salesforcecli/plugin-agent/pull/376))

* FIX: Salesforce DX projects now support these [metadata types](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json):

    * CnfgItemAttrDef
    * CnfgItemAttrPcklstValDef
    * CnfgItemAttrPicklistDef
    * CnfgItemAttrSetAttr
    * CnfgItemAttrSetDef
    * CnfgItemTypeAttrRelDef
    * CnfgItemTypeDef
    * CnfgItemTypeRelationDef
    * CnfgMgmtRelationTypeDef
    * CnfgMgmtCiSourceDef
    * MeetingPlaybookDefinition
    * TelemetryDefinition
    * TelemetryDefinitionVersion
    * TelemetryActionDefinition
    * TelemetryActionDefStep
    * TelemetryActnDefStepAttr

## 2.128.5 (March 25, 2026)

* NEW: The Lightning Local Dev CLI commands are now just-in-time (JIT). This means that when you update to this Salesforce CLI release and run a `lightning dev` command, Salesforce CLI checks if the associated [plugin-lightning-dev](https://github.com/salesforcecli/plugin-lightning-dev) is installed. If it's not, Salesforce CLI automatically installs it and then runs your command. These are the CLI commands included in this plugin:

    * `lightning dev app` : Preview a Lightning Experience app locally and in real-time, without deploying it.                                                                                     │
    * `lightning dev component` : Preview LWC components in isolation.                                                                                                                                   │
    * `lightning dev site` : Preview an Experience Builder site locally and in real-time, without deploying it.        

	See [Preview Components with Local Dev](https://developer.salesforce.com/docs/platform/lwc/guide/get-started-test-components.html) for information about using the commands.  These new commands will also soon be included in the [Salesforce CLI Command Reference](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_unified.htm). 

* NEW: Specify the version of an agent you want to activate with the new `--version` flag of `agent activate`. If you run the command without the `--version` flag, the command provides a list of agent versions for you to choose from. The value of `--version` is always a number, corresponding to the `vX` part of the `BotVersion` metadata in your project.

   For example, if you have a `force-app/main/default/bots/My_Agent/v4.botVersion-meta.xml` file in your project, then you activate this agent version in an org with alias `my-org` like this:

    ```bash
    sf agent activate --api-name My_Agent --version 4 --target-org my-org
    ```

   You can now also specify JSON output for the `agent activate` and `agent deactivate` commands with the new `--json` flag. (plugin-agent PR [#348](https://github.com/salesforcecli/plugin-agent/pull/348))
 
* CHANGE: For enhanced security, the minimum (and new default) value of the `--length` flag of the `org generate password` CLI command is now 20. If you specify a value less than 20, the command displays a message and uses 20 instead. Starting in Summer '26, the command will fail if you specify a password length less than 20.  The maximum value is still 100. (plugin-user PR [#1372](https://github.com/salesforcecli/plugin-user/pull/1372))

* FIX: The `project retrieve start` command now correctly retrieves specific versions of the `Bot` metadata type (`BotVersion`); previously it would retrieve just the latest version.  This example shows how to retrieve version 3 of the Local_Info_Agent `Bot`:

    ```bash
    sf project retrieve start --metadata Bot:Local_Info_Agent --metadata BotVersion:Local_Info_Agent.v3
    ```

    (source-deploy-retrieve PR [#1706](https://github.com/forcedotcom/source-deploy-retrieve/pull/1706))
  
* FIX: The `project deploy start` command now works correctly when you use both mechanisms for deleting metadata components at the same time: use a destructive change file (such as `--pre-destructive-changes manifest/destructiveChangesPre.xml`) and remove a different component from the standard manifest file (such as `--manifest manifest/package.xml`).  (source-deploy-retrieve PR [#1690](https://github.com/forcedotcom/source-deploy-retrieve/pull/1690), plugin-deploy-retrieve PR [#1508](https://github.com/salesforcecli/plugin-deploy-retrieve/pull/1508))

## 2.127.2 (March 18, 2026)

* FIX: The `data bulk export` CLI command now works correctly even when exporting many records (such as 700K+). (GitHub Issue [#3507](https://github.com/forcedotcom/cli/issues/3507), plugin-data PR [#1388](https://github.com/salesforcecli/plugin-data/pull/1388))

* FIX: You can now successfully retrieve individual `BotVersion` metadata components, such as `sf project retrieve start --metadata BotVersion:MyAgent.v1`.  (GitHub Issue [#3516](https://github.com/forcedotcom/cli/issues/3516), source-deploy-retrieve PR [#1704](https://github.com/forcedotcom/source-deploy-retrieve/pull/1704))

* FIX: You can now correctly deploy and retrieve `SchedulingObjective` metadata components.  (GitHub Issue [#3514](https://github.com/forcedotcom/cli/issues/3514), source-deploy-retrieve PR [#1700](https://github.com/forcedotcom/source-deploy-retrieve/pull/1700))

* FIX: Using `--flags-dir` to [read flag values from a file](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_flag_values_in_files.htm) now correctly works with commands in non-core third-party plugins. (GitHub Issue [#3493](https://github.com/forcedotcom/cli/issues/3493), oclif core PR [#1553](https://github.com/oclif/core/pull/1553), oclif plugin-plugins PR [#1288](https://github.com/oclif/plugin-plugins/pull/1288))

* FIX: Salesforce DX projects now support these [metadata types](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json):

    * MktDatalakeSrcKeyQualifier
    * ProcedurePlanDefinition
  
## 2.126.4 (March 11, 2026)

* NEW: The `dev generate flag` command now supports generating flags for commands that use the `src/commands/hello/world/index.ts` file layout in the plugin repo, in addition to `src/commands/hello/world.ts`. The command now also tries to find an existing messages file for adding the new flag's help text.

   Many thanks to [AndrewLPetersonSF](https://github.com/AndrewLPetersonSF) for contributing this useful feature! (plugin-dev PR #533)

* CHANGE: If you specify the `--json` flag for an interactive Agentforce DX command, but not a required flag, the command now correctly stops executing and displays an error. In this context, "interactive" refers to a command that prompts you for values if you don't explicitly specify a required flag. 

   For example, the `--name` flag is required for `agent generate authoring-bundle`. 

    * If you run `sf agent generate authoring-bundle`, then you're prompted for the name of the authoring bundle.
    * If you run `sf agent generate authoring-bundle --json`, then the command returns an error because in this case you must specify `--name`.

    (plugin-agent PR [#336](https://github.com/salesforcecli/plugin-agent/pull/336))

* FIX: We fixed an issue in how Salesforce CLI recognizes the shell that it's being run from. (oclif GitHub Issue [#1538](https://github.com/oclif/core/issues/1538), oclif core PR [#1548](https://github.com/oclif/core/pull/1548))

## 2.125.1 (March 4, 2026)

* NEW: When generating an authoring bundle with the `agent generate authoring-bundle` Agentforce DX command, use the `--force-overwrite` flag to overwrite the existing authoring bundle if one with the same API name already exists locally. For example:

    ```bash
    sf agent generate authoring-bundle --no-spec --api-name My_Authoring_Bundle --force-overwrite
    ```
    (plugin-agent PR [#327](https://github.com/salesforcecli/plugin-agent/pull/327))

## 2.124.7 (Feb 25, 2026)
 
* NEW: Generate an Experience Cloud site in your DX project with the new `template generate digital-experience site` command. After you pass the command the name of a template (currently only `BuildYourOwnLWR`), the new site name, and an URL path prefix, all the required metadata files are created locally. The metadata files correspond to metadata components such as DigitalExperienceConfig, DigitalExperienceBundle, Network, and CustomSite.

    The `BuildYourOwnLWR` template creates super-fast digital experiences, such as websites, microsites, and portals, using the Lightning Web Components programming model. Powered by Lightning Web Runtime (LWR), this customizable template delivers unparalleled site performance.  For additional details, see this Salesforce Help topic: https://help.salesforce.com/s/articleView?id=experience.rss_build_your_own_lwr.htm.

  Here's an example that generates the metadata files in the `force-app/main/default` directory:

  ```bash
  sf template generate digital-experience site --template BuildYourOwnLWR --name mysite --url-path-prefix mysite --output-dir force-app/main/default
  ```

  (plugin-templates PR [#829](https://github.com/salesforcecli/plugin-templates/pull/829))

* NEW: Generate a FlexiPage in your DX project with the new `template generate flexipage` command.  FlexiPages are the metadata types associated with a Lightning page, which represents a customizable screen made up of regions containing Lightning components.  You can generate these types of FlexiPages: `AppPage`, `HomePage`, or `RecordPage`.

   This example generates a `RecordPage` Flexipage for the Account object in the `force-app/main/default/flexipages` directory:
  ```bash
  sf template generate flexipage --name Account_Record_Page --template RecordPage --sobject Account --output-dir force-app/main/default/flexipages
  ```
  (plugin-templates PR [#833](https://github.com/salesforcecli/plugin-templates/pull/833))

* CHANGE: We reorganized all the commands in [plugin-templates](https://github.com/salesforcecli/plugin-templates) under a top-level topic called `template generate`. As a result, you can now take advantage of autocomplete to list all the available templates to generate things, such as DX projects or Apex classes. 

   But don't worry, we also added aliases to the moved commands, so that the old command names will still work. But they display a deprecation warning that the command name has changed.

   Here are all the affected commands. (plugin-templates PR [#840](https://github.com/salesforcecli/plugin-templates/pull/840), plugin-templates PR [#838](https://github.com/salesforcecli/plugin-templates/pull/838))

  | Old command | New command |
  | ----------- | ----------- |
  | apex generate class | template generate apex class |
  | apex generate trigger | template generate apex trigger |
  | analytics generate template | template generate analytics template |
  | lightning generate app | template generate lightning app |
  | lightning generate component | template generate lightning component |
  | lightning generate event | template generate lightning event |
  | lightning generate interface | template generate lightning interface |
  | lightning generate test | template generate lightning test |
  | project generate | template generate project |
  | static-resource generate | template generate static-resource |
  | visualforce generate component | template generate visualforce component |
  | visualforce generate page | template generate visualforce page |

* FIX: Salesforce CLI now properly shuts down node processes after sending telemetry events. (GitHub Issues [#3505](https://github.com/forcedotcom/cli/issues/3505) and [#3506](https://github.com/forcedotcom/cli/issues/3506), plugin-telemetry PR [#835](https://github.com/salesforcecli/plugin-telemetry/pull/835))

## 2.123.1 (Feb 18, 2026)

* NEW: **(Generally Available) Build Enterprise-Ready Agents with Agentforce DX and Agent Script**

  After a successful [beta](./README.md#211515-dec-10-2025), we're happy to announce the generally availability of Agentforce DX to build hybrid reasoning Salesforce agents that use Agent Script. These new types of agents have both the predictability that your business demands and the creativity that large language models (LLMs) make possible. Agentforce DX helps pro-code developers build these agents by minimizing context switching, enabling professional DevOps, and simplifying collaboration between low-code and pro-code developers.

  For the list of features we announced in the beta, see [these release notes](https://help.salesforce.com/s/articleView?id=release-notes.rn_tools_afdx_nga_beta.htm&release=260&type=5). Since the beta announcement, we've added or improved the following features:
  - **Agentforce Vibes Rules for Agent Script**: Agentforce Vibes now includes a global rule for coding Agent Script files. 
  - **Improved Agent Preview**: Previewing an agent now works the same regardless of how you started the conversation (using an Agent Script file or a published agent.)  Previously you had to configure additional security using a connected app to preview a published agent.
  - **Programmatic Agent Preview**: (Beta) Preview an agent programmatically, without starting an interactive session, with these four new CLI commands; this feature is particularly useful when you want an agent to test your agent.
    - `agent preview start`:     Start a programmatic agent preview session.
    - `agent preview send`:      Send a message to an existing agent preview session.
    - `agent preview sessions`:  List all known programmatic agent preview sessions.
    - `agent preview end`:  End an existing programmatic agent preview session and get trace location.
  - **Enhanced Session Tracer**: Get oodles of useful session trace information with the enhanced Agent Tracer panel in VS Code.  
  - **Simpler Authoring Bundle Generation**: You're no longer required to generate an agent spec YAML file when generating an authoring bundle. This feature makes it even easier to get started with Agent Script agents.

   The version of the Agentforce DX for VS Code Extension that contains these GA features is 1.7.0; install it from either the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-agents) or [Open VSX Registry](https://open-vsx.org/extension/salesforce/salesforcedx-vscode-agents).

  See the [Build Agents with Agentforce DX](https://developer.salesforce.com/docs/ai/agentforce/guide/agent-dx.html) section of the _Agentforce Developer Guide_ for details. 

* NEW: Generate a package ZIP file that you can use for debugging or to examine the package contents when you run `package version create` with the new `--generate-pkg-zip` flag.

  This example creates a package version from the contents of the `common` directory and gives it an installation key of `password123` and generates a package ZIP file:

  ```
  $ sf package version create --path common --installation-key password123 --generate-pkg-zip --target-dev-hub my-dev-hub
  ```
    (plugin-packaging PR [#1117](https://github.com/salesforcecli/plugin-packaging/pull/1117))

* FIX: Retrieving DigitalExperienceBundle metadata components now works correctly after you update the Digital Experience site in the org.

    Specifically, let's say you created a page in the Digital Experience site using the in-org builder, and then retrieved it to your DX project with the `project retrieve start` CLI command. You then change the mobile layout in the org, and retrieve the metadata again.  Before this fix, the `mobile.json` file was incorrectly created at the top-level of the page; now it's correctly nested in `mobile/mobile.json`. (source-deploy-retrieve PR [#1680](https://github.com/forcedotcom/source-deploy-retrieve/pull/1680))

* FIX: CLI commands that don't require an org no longer run really slowly in directories in which the `target-org` config variable points to a long-expired scratch org. (GitHub Issue [#3425](https://github.com/forcedotcom/cli/issues/3425), jsforce PR [#1772](https://github.com/jsforce/jsforce/pull/1772))

## 2.122.6 (Feb 11, 2026)

* NEW: Skip retrieving new or changed metadata from your org when you publish an agent's authoring bundle with the new `--skip-retrieve` flag of `agent publish authoring-bundle`.  This feature is useful when you publish the authoring bundle in a CI job and don't need to retrieve the metadata back to your DX project because it already has it; skipping the retrieve can save time. This example shows how to publish an authoring bundle with API name `MyAuthoringBundle` to the org with alias `my-dev-org`, but not retrieve any of the metadata:
  
    ```bash
    sf agent publish authoring-bundle --api-name MyAuthoringbundle --skip-retrieve --target-org my-dev-org
    ```
    
     (plugin-agent PR [#304](https://github.com/salesforcecli/plugin-agent/pull/304), agents PR [#204](https://github.com/forcedotcom/agents/pull/204))

* FIX: When you specify flag values in files via the `--flags-dir` flag, overriding the flags at the command-line now works correctly for all types of flags. Previously, the command would fail if you overrode a flag using its long flag name when it also has a short name.

    Thank you, [Jon Freed](https://github.com/jon-freed), for your contribution. This is your second one in two weeks, you're now quite the expert on `--flags-dir`. Do you have a third one coming up? Ha, no pressure!  But seriously, we love your contribution, thanks again.  (GitHub Issue [#3486](https://github.com/forcedotcom/cli/issues/3486), cli PR [#2554](https://github.com/salesforcecli/cli/pull/2554))

* FIX: The `project deploy start` command now correctly handles an empty `deploy-cache.json` file (an internal file that the CLI uses to manage deployments) rather than throwing a confusing error.  (GitHub Issue [#3387](https://github.com/forcedotcom/cli/issues/3387), sfdx-core PR [#1260](https://github.com/forcedotcom/sfdx-core/pull/1260))

## 2.121.7 (Feb 4, 2026)

* NEW: Open your org right in Agentforce Studio, specifically in the list view that displays all your agents, with the new `org open authoring-bundle` command. This example opens Agentforce Studio in an org with alias `my-org`; the command opens the browser in incognito mode:

     ```bash
     sf org open authoring-bundle --private --target-org my-org
     ```
     
* CHANGE: Previewing a published agent with the `agent preview` CLI command no longer requires the extra security of a specially-configured connected app. Rather, use the standard way to authorize the org in which the published agent is active (such as with the `org loging web` command) and then you can immediately use `agent preview` to chat with it.  As a result of this change, we've removed the `--client-app` flag from `agent preview` because it's no longer needed. 

    When you run the `agent preview` command without arguments, the list of published agents you can chat with are prepended with the label `(Published)`.  Agents labeled `(Agent Script)` are local to your DX project and the `agent preview` command uses their local Agent Script file in your DX project to preview it.  

* CHANGE: Over the next few weeks we're ending support for these two operating system-specific installers and TAR files:

    * Windows x86
    * Linux ARM
 
    We are removing the download button for the [Windows x86](https://developer.salesforce.com/tools/salesforcecli) installer from the download page (the Linux ARM TAR file was already removed). We'll keep some [old versions](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_install_cli.htm#sfdx_setup_install_cli_olderversions) for a while, but they too will become unavailable in the future. 

* FIX: Salesforce DX projects now support the WebApplication [metadata type](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json).

## 2.120.3 (Jan 27, 2026)

* NEW: Improve the usability and maintainability of the [configuration files that contain flag values](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_flag_values_in_files.htm) by adding comments that begin with either `#` or `//`.  For example, let's say that the file `flags/sobject` in your DX project contains the value of the `--sobject` flag of `data create record`.  You can comment the file like this:

    ```bash
    # Create a record in the Account object
    Account
    ```

     Thank you, [Jon Freed](https://github.com/jon-freed), for contributing the code for this excellent new feature. It definitely makes the "flags-dir" feature easier to use and maintain. We love it! (This new feature actually released back in November 2025, so apologies for the tardy announcement.) (cli PR [#2399](https://github.com/salesforcecli/cli/pull/2399))

* FIX: We improved the performance of the `project retrieve start` command. In particular, retrieves of large metatdata components, such as massive static resources, now finish correctly rather than hanging indefinitely. (sfdx-core PR [#1256](https://github.com/forcedotcom/sfdx-core/pull/1256), jsforce PR [#1784](https://github.com/jsforce/jsforce/pull/1784))

* FIX: The `package version` commands now work correctly when specifying `--api-version 60.0` (or lower); previously, some commands returned the `ErrorInvalidIdNoMatchingVersionIdError` error. (GitHub Issue [#3481](https://github.com/forcedotcom/cli/issues/3481), packaging PR [#796](https://github.com/forcedotcom/packaging/pull/796), plugin-packaging PR [#1108](https://github.com/salesforcecli/plugin-packaging/pull/1108))

* FIX: If you create a second sys admin user in a scratch org, and then authorize the scratch org using that second username, then the  `org list` command now correctly lists that org with the second username.  (GitHub Issue [#3439](https://github.com/forcedotcom/cli/issues/3439), plugin-org PR [#1551](https://github.com/salesforcecli/plugin-org/pull/1551))

* FIX: Logging out of multiple orgs with the `org logout --all` command, and deselecting the ones you want to stay logged into, is now working correctly. (GitHub Issue [#3296](https://github.com/forcedotcom/cli/issues/3296), plugin-auth PR [#1437](https://github.com/salesforcecli/plugin-auth/pull/1437), sfdx-core PR [#1255](https://github.com/forcedotcom/sfdx-core/pull/1255))

## 2.119.8 (Jan 20, 2026)

* CHANGE: We removed the `org login device` command from Salesforce CLI, as announced on [August 27, 2025](./README.md#21037-aug-27-2025). 

    We removed the command because it uses the the OAuth 2.0 device flow, which is being blocked by Salesforce. For details see [Prepare for Connected App Usage Restrictions Change](https://help.salesforce.com/s/articleView?id=005132365&type=1&utm_source=techcomms&utm_medium=email&utm_campaign=FY26_Core_4013001).

    Use one of these commands instead of `org login device`:
  
    *  [`org login jwt`](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_auth_jwt_flow.htm) to authorize an org in headless environments, such as CI.
    *  [`org login web`](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_auth_web_flow.htm) to authorize an org using a browser.

* FIX: We fixed a bug that caused deploys and retrieves to hang indefinitely during certain connection errors. (source-deploy-retrieve PR [#1663](https://github.com/forcedotcom/source-deploy-retrieve/pull/1663))

* FIX: Users who have the Manage Dev Sandboxes user permission can now successfully run the `org refresh sandbox` command. (plugin-org PR [#1569](https://github.com/salesforcecli/plugin-org/pull/1569))

* FIX: We fixed all known issues when using Node.js v25 with Salesforce CLI. We still officially support v24, which is the [Active LTS version of Node.js](https://nodejs.org/en/about/previous-releases).

* FIX: When creating a sandbox with the `org create sandbox` command, you can now list the features in the sandbox definition file as either an array (`"features": ["SandboxStorage"]`) or a string (`"features": "['SandboxStorage']"`). (GitHub Issue [#3479](https://github.com/forcedotcom/cli/issues/3479), sfdx-core PR [#1254](https://github.com/forcedotcom/sfdx-core/pull/1254))

* FIX: Salesforce DX projects now support the FlexcardDefinition [metadata type](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json).

## 2.118.20 (Jan 14, 2026)

* FIX: We fixed some under-the-hood bugs.

## 2.117.7 (Jan 7, 2026)

* NEW: The debug log information outputted by the `--dev-debug` flag now includes the list of files that were ignored during a deployment or retrieval.  This information is useful to debug your `.forceignore` file and understand exactly what's being ignored when you run `project deploy|retrieve start`. (GitHub Issue [#3345](https://github.com/forcedotcom/cli/issues/3345), source-deploy-retrieve PR [#1656](https://github.com/forcedotcom/source-deploy-retrieve/pull/1656))

* UPDATE: Use the existing `package update` command to set the recommended version of a package. When you set a package version as the recommended version, your subscribers see an **Upgrade to Recommended Version** option on the Installed Packages page in their org. Only released package versions can be set as the recommended version. This example sets `PackageA@1.0 as` the recommended version.

    ```bash
    sf package update --package 0Ho.. --target-dev-hub devhub@example.com --recommended-version-id PackageA@1.0  
    ```

   Run `package update --help` for more information. NOTE: This feature is available for only Spring '26 orgs (API version 66.0).

* FIX: Salesforce DX projects now support these [metadata types](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json):

	* IntegArtifactDef
	* OnboardingDataObjectGroup
	* PartyProfileDataObjectValidityDefinition

## December 23 and 30, 2025

Due to the holiday break in the United States, we aren't releasing new stable versions. Happy holidays!

## 2.116.6 (Dec 17, 2025)

* NEW: Specify the number of seconds to poll the org to check for the test status when you run `apex test run` with the new `--poll-interval`.  Previously the poll interval was hard-coded to 1 second. This example shows how to set the poll interval to 5 seconds:

    ```bash
     sf apex run test --class-names MyClassTest --result-format human --poll-interval 5 --target-org my-org
    ```

  (GitHub Issue [#3456](https://github.com/forcedotcom/cli/issues/3456), plugin-apex PR [#832](https://github.com/salesforcecli/plugin-apex/pull/832), salesforcedx-apex PR [#597](https://github.com/forcedotcom/salesforcedx-apex/pull/597))

* FIX: If an org is configured to block API connections, running one of the `org login` CLI commands now fails quickly rather than going into a loop until, for example, maximum login requests are reached. (GitHub Issue [#3428](https://github.com/forcedotcom/cli/issues/3428), sfdx-core PR [#1248](https://github.com/forcedotcom/sfdx-core/pull/1248), jsforce PR [#1774](https://github.com/jsforce/jsforce/pull/1774))

* FIX: Salesforce DX projects now support the `StageAssignment` [metadata type](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json). 

## 2.115.15 (Dec 10, 2025)

* NEW: (Beta) Build complex, deterministic, enterprise-ready agents with Agent Script and Agentforce DX.

    Agentforce DX is the pro-code equivalent of the newly-released [Agentforce Builder](https://help.salesforce.com/s/articleView?id=release-notes.rn_einstein_agent_builder.htm&release=258&type=5) UI that runs in your org. See [Author an Agent with Agentforce DX](https://developer.salesforce.com/docs/einstein/genai/guide/agent-dx-nga-author-agent.html) in the _Agentforce Developer Guide_ for more information.  New features include: 

   * Author agents using [Agent Script](https://developer.salesforce.com/docs/einstein/genai/guide/agent-script.html), the language for building Salesforce agents. Agent Script combines the flexibility of using natural language for code generation with the reliability of programmatic expressions for handling business rules.

   * Easily edit Agent Script files in the VS Code editor with the new [Agent Script VS Code extension](https://marketplace.visualstudio.com/items?itemName=salesforce.agent-script-language-client), which provides standard code editing features: syntax highlighting, visual syntax cues (such as red squiggles for errors), internal validation, and Outline support.
   
   * Preview an agent conversation from its Agent Script file and get the behind-the-scenes details of how your agent is working with the updated [Agentforce DX VS Code Extension](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-agents) The preview supports two modes: simulated (which mocks data) and live mode (which uses real Apex classes, flows, and other resources).
 
   * Generate, validate, and publish an _authoring bundle_ with these new CLI commands. An authoring bundle is a new metadata type ([AiAuthoringBundle](https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_aiauthoringbundle.htm)) that represents an agent that uses Agent Script as its blueprint. 
        * `agent generate authoring-bundle`: Generate an authoring bundle from an existing agent spec YAML file. 
        * `agent validate authoring-bundle`: Validate an authoring bundle to ensure its Agent Script file compiles successfully and can be used to publish an agent.
        * `agent publish authoring-bundle`: Publish an authoring bundle to your org, which results in a new agent or a new version of an existing agent.
  
* FIX: You no longer get an error if you run `apex run test` asynchronously, such as with the `--wait 0` flag, and also specify an output format or `--code-coverage`. (GitHub Issue [#2963](https://github.com/forcedotcom/cli/issues/2963), salesforcedx-apex PR [#596](https://github.com/forcedotcom/salesforcedx-apex/pull/596))

* FIX: The `org login web` command, when run with the `--scopes` flag, now correctly requests the specified authentication (OAuth) scopes, rather than always requesting the default scopes (`refresh_token api web`). (plugin-auth PRs [#1420](https://github.com/salesforcecli/plugin-auth/pull/1420) and [#1423](https://github.com/salesforcecli/plugin-auth/pull/1423))

## 2.114.5 (Dec 3, 2025)

* NEW: (Beta) Specify that you want to run only relevant Apex tests when you deploy metadata to your org with the new `RunRelevantTests` value of the `--test-level` flag of the `project deploy start|validate` and `project delete source` commands.

    Salesforce automatically identifies the relevant tests based on an analysis of the deployment payload and the payload dependencies. For fine-grained control, you can also annotate test classes so that they always run in certain conditions. See [@IsTest Annotation](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_isTest.htm) in the _Apex Developer Guide_. Each class and trigger in the deployment package must be covered by the executed tests for a minimum of 75% code coverage. This coverage is computed for each class and triggers individually and is different than the overall coverage percentage.
 
    **NOTE**: This feature is available only for Spring '26 orgs (API version 66.0). 

    This example deploys source files in the `force-app` package directory to the org with alias `my-scratch` and runs only the Apex tests that are relevant to the actual metadata that's being deployed:

    ```bash
    sf project deploy start --source-dir force-app --test-level RunRelevantTests --target-org my-scratch
    ```
    (plugin-deploy-retrieve PR [#1479](https://github.com/salesforcecli/plugin-deploy-retrieve/pull/1479), source-deploy-retrieve PR [#1644](https://github.com/forcedotcom/source-deploy-retrieve/pull/1644))

* FIX: The `project retrieve start` command now correctly fails and outputs an error message if you specify an output directory (with the `--output-dir` flag) that is outside of the Salesforce DX project. (GitHub Issue [#3432](https://github.com/forcedotcom/cli/issues/3432), plugin-deploy-retrieve PR [#1480](https://github.com/salesforcecli/plugin-deploy-retrieve/pull/1480))

* FIX: Salesforce DX projects now support these [metadata types](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json):

    * AccountPlanObjMeasCalcDef (GitHub Issue [#3395](https://github.com/forcedotcom/cli/issues/3395))
    * LightningOutApp (GitHub Issue [#3435](https://github.com/forcedotcom/cli/issues/3435))
    * DataObjectSearchIndexConf (GitHub Issue [#3441](https://github.com/forcedotcom/cli/issues/3441))

## Nov 26, 2025

Due to the Thanksgiving break in the United States, we aren't releasing a new stable version. Happy Thanksgiving!

## 2.113.6 (Nov 19, 2025)

* FIX: We fixed some under-the-hood bugs.

## 2.112.6 (Nov 12, 2025)

**ANNOUNCEMENT OF UPCOMING CHANGES**

* **`plugins link` Command**: (This change impacts Salesforce CLI plugin developers who use `yarn` as their package manager.) Starting March 2026, the `plugins link` command will no longer automatically install dependencies after it links the specified plugin into Salesforce CLI. You will need to run `yarn` manually to install the required dependencies before you run `plugins link`. In this release, the `plugins link` command has been updated to include a reminder about this upcoming change.  This change doesn't impact plugin developers who use `npm` or `pnmp` as their package manager because those types of plugins already don't get dependencies automatically installed when linked.  (oclif plugin-plugins PR [#1230](https://github.com/oclif/plugin-plugins/pull/1230))
* **Bundled Node.js Version**: Starting February 2026, the Salesforce CLI installer for Windows, macOS, and Linux tarballs will start bundling Node.js v24 (Current LTS) instead of Node.js v22 (Maintenance LTS).  See [this pinned GitHub issue](https://github.com/forcedotcom/cli/issues/3445) for additional information. 

## 2.111.7 (Nov 5, 2025)

* NEW: Retrieve package metadata for a specified package version with the new `package version retrieve` command. Package metadata can be retrieved for only second-generation managed package versions or unlocked packages.

   This example shows how to retrieve package metadata for a converted subscriber package version ID (starts with 04t) into `my-directory/` within your Salesforce DX project directory:

  ```bash
  sf package version retrieve --package 04tXXX --output-dir my-directory/ --target-dev-hub devhub@example.com
  ```

* FIX: Salesforce DX projects now support the FlowValueMap [metadata type](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json).
 
## 2.110.22 (Oct 29, 2025)

* FIX: Using the `SF_MDAPI_TEMP_DIR` environment variable when running `project retrieve start` now generates a correct directory name on Windows. (GitHub Issue [#3416](https://github.com/forcedotcom/cli/issues/3416), plugin-deploy-retrieve PR [#1460](https://github.com/salesforcecli/plugin-deploy-retrieve/pull/1460), source-deploy-retrieve PR [#1635](https://github.com/forcedotcom/source-deploy-retrieve/pull/1635))

* FIX: The `org open` and `org open agent` commands now correctly generate frontdoor URLs so you can now successfully use the `--source-file` flag to open the org at a specific builder, such as  or Agentforce Builder or the setup page for Apex classes. (GitHub Discussion [#3427](https://github.com/forcedotcom/cli/discussions/3427), plugin-org PR [#1529](https://github.com/salesforcecli/plugin-org/pull/1529))

* FIX: Salesforce DX projects now support these [metadata types](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json):

    * ComputeExtension
    * DataMapperDefinition
    * GiftEntryGridTemplate
    * IntegrationProcdDefinition
    * McpServerDefinition
    * OmniscriptDefinition

## 2.109.7 (Oct 22, 2025)

* NEW: If you authorize an org with the `org login web` CLI command, but it runs into an issue during the org login process, the CLI command now times out after 2 minutes rather than hang indefinitely. You can customize the number of milliseconds that the command waits to timeout with the new SF_WEB_OAUTH_SERVER_TIMEOUT environment variable.  The default value is 120000 (2 minutes). This example sets the timeout to 3 minutes:

    ```bash
    export SF_WEB_OAUTH_SERVER_TIMEOUT=180000
    ```
    (sfdx-core PR [#1245](https://github.com/forcedotcom/sfdx-core/pull/1245), sfdx-core PR [#1246](https://github.com/forcedotcom/sfdx-core/pull/1246))

## Oct 8 and 15, 2025

Due to Dreamforce, we aren't releasing a new stable version on these dates. If you're attending Dreamforce, stop by Moscone West and say hello!

## 2.108.6 (Oct 1, 2025)

* FIX: Salesforce DX projects now support the TransactionProcessingType [metadata type](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json). 

## 2.107.6 (Sept 24, 2025)

* NEW: (Beta) Run tests for multiple Salesforce features, such as Apex classes and Flows, in a single and unified way with these new commands:

    - `logic run test`: Invoke tests for Apex and Flows in an org.
    - `logic get test`: Get the results of a test run if it timed out.  

    Running the tests together with a single command ensures seamless interoperability between the features.

    Many flags of these new commands mimic the flags for the existing `apex run|get test` and `flow run|get test` commands, such as `--tests`, `--test-level`, `--code-coverage`, `--class-names`, `--output-dir`, and more.  But the new `logic run test` command expands the `--tests` flag so that you can specify _both_ Apex and Flow tests and adds a `--test-category` flag to narrow the type of tests you want to run.  To specify a flow test, use this format: `FlowTesting.<name-of-flow-test>`. Run `sf logic run test --help` for more information about getting the exact name of a Flow test. 

  By default, the `logic run test` command executes asynchronously and returns a test run ID. Then use the `logic get test` command to retrieve the results. If you want to wait for the test run to complete and see the results in the command output, use the `--synchronous` flag.

  This example runs all local Apex and Flow tests in the org with alias `my-scratch` asynchronously:

  ```bash
  sf logic run test --test-level RunLocalTests --test-category Apex --test-category Flow --target-org my-scratch
  ```

  The command returns a test run ID which you pass to the `logic get test` command to get the test results:

  ```bash
  sf logic get test --test-run-id <test-run-id>
  ```
  (plugin-apex PR [#792](https://github.com/salesforcecli/plugin-apex/pull/792) and [#795](https://github.com/salesforcecli/plugin-apex/pull/795))


* CHANGE: As we noted in the [April 30, 2025](README.md#2869-april-30-2025) release notes, Salesforce CLI now returns an error when you run `org logout` on an org that you haven't authorized; since April the command displayed only a warning. The exit code in this scenario has also changed from 0 to 1. (GitHub Issue [#3247](https://github.com/forcedotcom/cli/issues/3247), plugin-auth PR [#1366](https://github.com/salesforcecli/plugin-auth/pull/1366))

* FIX: We fixed a regression in the `apex run test` command so that it now makes the expected number of API calls. (GitHub Issue [#3380](https://github.com/forcedotcom/cli/issues/3380), salesforcedx-apex PR [#569](https://github.com/forcedotcom/salesforcedx-apex/pull/569))

* FIX: We increased the request timeout period in the JSForce `node-fetch` wrapper to prevent Salesforce CLI commands (such as `org create scratch`) from timing out too quickly. (GitHub Issue [#3354](https://github.com/forcedotcom/cli/issues/3354), jsforce PRs [#1738](https://github.com/jsforce/jsforce/pull/1738) and [#1745](https://github.com/jsforce/jsforce/pull/1745))

* FIX: We fixed the Salesforce CLI telemetry dependencies and now the CLI is using all the correct licenses. (GitHub Issue [#3392](https://github.com/forcedotcom/cli/issues/3392), telemetry PR [#450](https://github.com/forcedotcom/telemetry/pull/450))

* FIX: We updated `apex run test` to align with the changed API response in v65.0, which in turned fixed the TypeError in `apex get test`. (GitHub Issue [#3389](https://github.com/forcedotcom/cli/issues/3389), salesforcedx-apex PR [#568](https://github.com/forcedotcom/salesforcedx-apex/pull/568))

## 2.106.6 (Sept 17, 2025)

* FIX: We fixed a Windows security vulnerability to ensure that the Salesforce CLI installer always executes the correct `cmd.exe` file. (cli PR [#2365](https://github.com/salesforcecli/cli/pull/2365), oclif PR [#1852](https://github.com/oclif/oclif/pull/1852))

## 2.105.6 (Sept 10, 2025)

* ANNOUNCEMENTS:
    
	* Starting 8/28/2025, the OAuth 2.0 Device Flow is blocked in the default `Salesforce CLI` connected app. See the [pinned issue](https://github.com/forcedotcom/cli/issues/3368) for more information. 
	* Starting in December 2025, the `project deploy start` and `project retrieve start` commands will require that the target org use source tracking, unless you specify the metadata you want to deploy or retrieve. If you deploy or retrieve to an org that doesn’t use source tracking, then you must specify the metadata you want to deploy or retrieve. See the [pinned issue](https://github.com/forcedotcom/cli/issues/3375) for more information.

------------

* FIX: We fixed some under-the-hood bugs.

## 2.104.6 (Sept 3, 2025)

* FIX: Salesforce DX projects now support these [metadata types](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json):

    * FieldMappingConfig
    * FieldMappingConfigItem

## 2.103.7 (Aug 27, 2025)

* NEW: Check out the new release of the [Agentforce DX for VS Code extension](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-agents)! You can now chat with an active agent using the new Agent Preview panel to see how the agent responds to your statements, questions, and commands (utterances). This feature is the VS Code equivalent of the `agent preview` CLI command.  And if an agent action that's implemented with an Apex class encounters an error, you can use **Debug Mode** during the chat to automatically invoke the [Apex Replay Debugger](https://developer.salesforce.com/docs/platform/sfvscode-extensions/guide/replay-debugger.html).

    See the [README](https://github.com/forcedotcom/vscode-agents/blob/HEAD/README.md#preview-an-agent-and-debug-the-conversation) for prerequisites and instructions for using this feature. 

* NEW and CHANGED: Last week (in version 2.102.6), we introduced a new feature to display details about an invoked action when running agent tests with the `agent test run|resume|report` CLI commands. These details are in JSON format and displayed in the Generated Data section of the test results. Depending on the action, the JSON can get pretty long. So for simplicity, we no longer output these details _by default_; instead, use the new `--verbose` flag to output the details. This example runs an agent test and specifies that the output should include the generated data:

    ```bash
    sf agent test run --api-name Resort_Manager_Test --verbose --wait 40
    ```
    
    (plugin-agent PR [#189](https://github.com/salesforcecli/plugin-agent/pull/189))

* CHANGE: We removed the `--async` flag of each of these commands:

    * `data delete bulk`
    * `data export bulk`
    * `data import bulk`
    * `data update bulk`
    * `data upsert bulk`

    The commands don't need the `--async` flag because they're asynchronous by default. We deprecated the flag back in [April 23, 2025)](./README.md#2857-april-23-2025. (plugin-data PR [#1303](https://github.com/salesforcecli/plugin-data/pull/1303))

* CHANGE: We deprecated the `org login device` command and will remove it from Salesforce CLI in the near future. It's also now hidden, so it won't appear when you run `sf org login -h`. 

    We are taking these actions because the command uses the the OAuth 2.0 device flow, which is being blocked.  For details see [Prepare for Connected App Usage Restrictions Change](https://help.salesforce.com/s/articleView?id=005132365&type=1&utm_source=techcomms&utm_medium=email&utm_campaign=FY26_Core_4013001).

    We recommend that instead of `org login device`, you use one of these other commands:
  
    *  [`org login jwt`](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_auth_jwt_flow.htm) to authorize an org in headless environments, such as CI.
    *  [`org login web`](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_auth_web_flow.htm) to authorize an org using a browser.

* FIX: Salesforce DX projects now support the UiPreviewMessageTabDef [metadata type](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json). 

## 2.102.6 (Aug 20, 2025)

* NEW: Easily activate or deactivate an agent in your org when using the [VS Code Agentforce DX extension](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-agents) by right-clicking on one of the agent's Bot metadata files and clicking **SFDX: Activate Agent** or **SFDX: Deactivate Agent**. The agent's Bot metadata files are in the `bots` folder of your package directory (`force-app` by default).

    Activating an agent makes it immediately available to your users. If you deactivate a currently-active agent, which makes it unavailable to users, you're prompted to confirm. Only one agent version can be active at a time, so if you activate a new version, the old one is deactivated. 

    If you (de)activate an agent from its Bot folder or its main Bot metadata file (such as `Resort_Manager.bot-meta.xml`), the latest agent version is (de)activated. To (de)activate a non-latest version, right-click on its version file, such as `v1.botVersion-meta.xml`. (vscode-agents PR [#55](https://github.com/forcedotcom/vscode-agents/pull/55))

* NEW: When running agent tests with the `agent test run|resume|report` CLI commands or from the VS Code Agent Testing Panel, and a test utterance invoked an action, the test results now include details about the invoked action in JSON format. Details include any Apex classes or Flows that were invoked, any Salesforce objects that were touched, and so on.  (plugin-agent PR [#185](https://github.com/salesforcecli/plugin-agent/pull/185))

* CHANGE: As we announced in [March 2025](https://github.com/forcedotcom/cli/issues/3249), when you now use the `org open` command with the `--json` or `--url-only` flags, the generated URLs in the output will be single-use only. This means that the URLs can be used only one time; subsequent use won’t allow you to log into the org.  The URLs also expire 60 seconds after they are generated. Finally, as a result of this change, we no longer support the `SF_SINGLE_USE_ORG_OPEN_URL` environment variable. (plugin-org PR [#1484](https://github.com/salesforcecli/plugin-org/pull/1484))

* FIX: The CatalogedApiArtifactVerInfo metadata type has been correctly renamed CatalogedApiArtifactVersionInfo in the [metadata registry](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json). (source-deploy-retrieve PR [#1600](https://github.com/forcedotcom/source-deploy-retrieve/pull/1600))

## 2.101.5 (Aug 13, 2025)

* NEW: Easily activate or deactivate an agent in your org with the new `agent activate|deactivate` commands.  Activating an agent makes it immediately available to your users. 

  The two commands use the agent's API name; if you know it, use the `--api-name` flag to specify it. If you don't use the flag, the command lists the agents in your org for you to select. This example shows how to activate an agent with API name `Coral_Cloud_Agent` in your default org:

  ```bash
  sf agent activate --api-name Coral_Cloud_Agent
  ```

  This example prompts you to choose an agent to deactivate in the org with alias `my-org`:

  ```bash
  sf agent deactivate --target-org my-org
  ```

  (plugin-agent PR [#182](https://github.com/salesforcecli/plugin-agent/pull/182))

* NEW: Add more context to agent tests with the updated `agent generate test-spec` CLI command which now asks if you want to add boilerplate conversation history to each individual test case. The boilerplate is simply a template that you then edit with the specific history of a conversation that can happen before the test case's utterance.

  For example, let's say you're testing a shopping assistant agent, and a test case has the utterance of "When will my purchase arrive?".  To better test this utterance, you can add a conversation history like this:

  ```yaml
    conversationHistory:
      - role: user
        message: I purchased an item last week but it hasn't arrived yet.
      - role: agent
        message: What is your order ID?
        topic: ask_for_order_id
      - role: user
        message: It's 123456.
      - role: agent
        message: You ordered a Wacky Cat Bobblehead, right?  Great choice.
        topic: look_up_order
  ```

  The `agent generate test-spec` command uses the Agentforce Testing API under the covers. For more information, see [Conversation History](https://developer.salesforce.com/docs/einstein/genai/guide/testing-api-build-tests.html#conversation-history). (plugin-agent PR [#181](https://github.com/salesforcecli/plugin-agent/pull/181))

* NEW: Display the dependency graph for an unlocked or 2GP managed package version with the new `package version displaydependencies` CLI command. This example displays the dependencies of the specified package version in the order that the dependencies must be installed (root last):

    ```bash
    sf package version displaydependencies --package 04t... --edge-direction root-last --target-dev-hub devhub@example.com
    ```

    Run `sf package version displaydependencies` for additional examples and configuration information. (plugin-packaging PR [#1018](https://github.com/salesforcecli/plugin-packaging/pull/1018))

* CHANGE: We removed  the `@salesforce/sfdx-scanner` plugin from the list of JIT (just in time) plugins. As a result, you must manually install the plugin if you want to use a `scanner` command and the plugin isn't installed in Salesforce CLI.  We removed this plugin from the JIT list because it contains CLI commands for Code Analyzer v4, which being [retired](https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/guide/release-notes.md#code-analyzer-v4120-end-of-life). Use [Code Analyzer v5](https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/guide/code-analyzer.html) instead. (cli PR [#2322](https://github.com/salesforcecli/cli/pull/2322))

## 2.100.4 (Aug 6, 2025)

* NEW: Add custom evaluations to your agent test spec with the updated `agent generate test-spec` command, which now asks if you want to add one to a specific test case.  

    Custom evaluations test an agent response for specific strings or numbers. If you opt to add a custom evaluation to an agent test case, you'll be prompted for the following information:
  
     * Label: A descriptive name of the custom evaluation. 
     * JSONPath expression: Enables you to automatically point to the data you want to test. For details on how to construct a JSONPath expression, see [Dynamically Reference Generated Data](https://developer.salesforce.com/docs/einstein/genai/guide/testing-api-custom-evaluation-criteria.html#dynamically-reference-generated-data).
     * Comparison operator: The operator used to compare the expected and actual values returned from the test. Examples are equals, greater than or equal, and so on. 
     * Expected value: The value you expect after the evaluation is tested.
  
   The `agent generate test-spec` command uses the Agentforce Testing API under the covers. Therefore, for more information, see [Add Custom Evaluation Criteria to a Test Case](https://developer.salesforce.com/docs/einstein/genai/guide/testing-api-custom-evaluation-criteria.html#get-started-with-custom-evaluation-criteria). (plugin-agent PR [#177](https://github.com/salesforcecli/plugin-agent/pull/177))

* FIX: You can once again successfully create a scratch org asynchronously (`org create scratch --async`) and then resume its creation (`org resume scratch`).   (GitHub Issue [#3322](https://github.com/forcedotcom/cli/issues/3322), sfdx-core PR [#1207](https://github.com/forcedotcom/sfdx-core/pull/1207), plugin-org PR [#1473](https://github.com/salesforcecli/plugin-org/pull/1473))

* FIX: The `agent generate test-spec` command now works correctly with both the GenAiPlanner (legacy) and GenAiPlannerBundle (new) metadata types, both of which represent agent planners.  (plugin-agent PR [#174](https://github.com/salesforcecli/plugin-agent/pull/174))

* FIX: We updated the npm dependencies in our project templates so that you no longer get an error when you run `project generate` and then `npm install` in the DX project. (GitHub Issue [#3222](https://github.com/forcedotcom/cli/issues/3222), GitHub Issue [#3278](https://github.com/forcedotcom/cli/issues/3278), GitHub Issue [#3295](https://github.com/forcedotcom/cli/issues/3295))

* FIX: Salesforce DX projects now support these [metadata types](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json):

    * CatalogedApi
    * CatalogedApiVersion
    * CatalogedApiArtfctVerInfo
    * RuleLibraryDefinition (GitHub Issue [#3099](https://github.com/forcedotcom/cli/issues/3099))

## 2.99.6 (July 30, 2025)

* NEW: We improved the performance of deploys and retrieves. (source-deploy-retrieve PR [#1583](https://github.com/forcedotcom/source-deploy-retrieve/pull/1583), source-deploy-retrieve PR [#1591](https://github.com/forcedotcom/source-deploy-retrieve/pull/1591))

  Many thanks to Jon Freed ((@jon-freed)[https://github.com/jon-freed]), who is actually the "we" in the previous sentence. Jon contributed all the source code, which cleverly cuts back the number of string manipulations and simplifies key lookups, resulting in faster deployments and retrievals. We are delighted with your generous contribution. 

## 2.98.6 (July 23, 2025)

* NEW: We've improved the performance of `project deploy|retrieve start` when used with source tracking.  (source-tracking PRs [#794](https://github.com/forcedotcom/source-tracking/pull/794) and [#732](https://github.com/forcedotcom/source-tracking/pull/732))

   Big thanks to Luke Cotter ([@lukecotter](https://github.com/lukecotter)) who contributed all the code for this awesome performance improvement. Who doesn't love a faster metadata deployment? We really appreciate it, Luke!
   
* FIX: You can now successfully deploy a new custom field and updated workflow to your org when using decomposed workflows (beta) in your DX project. (GitHub Issue [#3320](https://github.com/forcedotcom/cli/issues/3320))

* FIX: Salesforce DX projects now support the ExternalStoragePrvdConfig [metadata type](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json).

## 2.97.6 (July 16, 2025)

* FIX: Running `project deploy start` with the `--dry-run` flag is now working correctly. (GitHub Issue [#3336](https://github.com/forcedotcom/cli/issues/3336), plugin-deploy-retrieve PR [#1395](https://github.com/salesforcecli/plugin-deploy-retrieve/pull/1395))

## 2.96.4 (July 9, 2025)

* FIX: Salesforce DX projects now support these [metadata types](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json):

    * ApiNamedQuery
    * ObjIntegProviderDefMapping
    * DataConnector
    * ExtlClntAppCanvasStngs
 
## 2.95.6 (July 3, 2025)

* FIX: Salesforce CLI now displays tables correctly when column size is resolved to 0 in some CI environments. (GitHub issue [#3317](https://github.com/forcedotcom/cli/issues/3317), oclif PR [#167](https://github.com/oclif/table/pull/167)

* FIX: You can now correctly clone a sandbox with Data Storage Upgrades. (GitHub issue [#3293](https://github.com/forcedotcom/cli/issues/3293), sfdx-core PR [#1205](https://github.com/forcedotcom/sfdx-core/pull/1205)

* FIX: The `sf agent generate test-spec` command no longer generates a Yaml file with an empty expectedActions array when the action contains single quotes. (GH issue [#3314](https://github.com/forcedotcom/cli/issues/3314), Agents PR [#115](https://github.com/forcedotcom/agents/pull/115))

* FIX: We fixed a bug in which the string replacement functionality incorrectly emits warning saying the string to replace was not found when processing large files. (GH issue [#3318](https://github.com/forcedotcom/cli/issues/3318), source-deploy-retrieve PR [#1577](https://github.com/forcedotcom/source-deploy-retrieve/pull/1577)) 

## 2.94.6 (June 25, 2025)

* FIX: The `sf project deploy start` command no longers modifies source-tracking info when using the `--dry-run` flag. (GitHub issue [#3243](https://github.com/forcedotcom/cli/issues/3243), plugin-deploy-retrieve PR [#1372](https://github.com/salesforcecli/plugin-deploy-retrieve/pull/1372)

* NEW: We’ve added a --code-coverage flag to the package convert command.

   Calculate and store the code coverage percentage by running the packaged Apex tests included in the package version. To promote a package version to released, you must use the --code-coverage flag. The package must also meet the code coverage requirements.

  This example converts the latest managed-released version of the 1GP package with the specified package ID and calculates code coverage; the example uses the default Dev Hub org:

  ```bash
    sf package convert --package 033... --code-coverage
  ```

## 2.93.7 (June 18, 2025)

* NEW: Link multiple connected apps in an org to an authenticated user, enabling Salesforce CLI commands to use these connected apps for API-specific requirements, like new OAuth scopes or JWT-based access tokens.

    As a result of this new feature, the authentication flow to use the `agent preview` CLI command to interact with an agent is now much easier. Previously you had to create a new Salesforce username for each Agentforce agent you wanted to interact with, and then specify it with the `--connected-app-user` flag. Now you use the same username you normally authenticate with, then specify the link to the connected app with the new `--client-app` flag. The `agent preview` command is currently the only CLI command that requires this feature.

    Let's see how this works. First, you create the link to a connected app by re-running the `org login web` command and using the `--client-id` flag to specify the connected app's consumer secret (also called _client id_).  You also specify these new flags:

    * `--client-app`: The name of the link to the connected app. You can specify any string you want. 
    * `--username`: The username of the authenticated user.  This is the username you specified when you originally authorized your org with `org login web`. 
    * `--scopes`: The OAuth scopes required by the CLI command that is going to use the link. 

    In this example, the resulting link is called `agent-app` which you later use with the command that requires this connected app, such as `agent preview`.  

    ```bash
    sf org login web --client-app agent-app --username jdoe@example.com --client-id 3MVG9XgkMlongstring --scopes "sfap_api chatbot_api refresh_token api web"
    ```

    Then use the new `--client-app` flag of the `agent preview` command to specify the link to the connected app.  For example: 

    ```bash
    sf agent preview --api-name "Resort_Manager" --client-app agent-app --target-org my-org
    ```

    (sfdx-core PR [#1188](https://github.com/forcedotcom/sfdx-core/pull/1188), plugin-auth PR [#1306](https://github.com/salesforcecli/plugin-auth/pull/1306), plugin-agent PR [#157](https://github.com/salesforcecli/plugin-agent/pull/157))

* NEW: We're happy to announce that the Source Mobility feature is now generally available (GA)!  With this feature you can move source files within your local Salesforce DX project without the source-tracking feature thinking that you've deleted and then recreated a metadata component. 

   A few things to keep in mind:

    * Now that source mobility is GA, the feature is enabled by default. To opt-out of the behavior, set the new SF_DISABLE_SOURCE_MOBILITY environment variable to `true`; the variable is `false` by default.
    * We removed the old environment variable for opting into the Beta feature (SF_BETA_TRACK_FILE_MOVES).
    * Source Mobility works with file _moves_, not file _renames_. Renaming a source file is still interpreted as deleting a metadata component and creating a new one with the different name.
    * Child source files can move only to an identically named parent. For example, a custom field can move between Object folders in different package directories only if both Object folders have the same name.

    Enjoy reorganizing your DX project source files! (source-tracking PR [#778](https://github.com/forcedotcom/source-tracking/pull/778))

* NEW: Simplify your packaging push upgrades by leveraging the four new CLI commands that let you schedule, abort, view details on on a specific package upgrade, or view a list of all push upgrade jobs:

    * `package push-upgrade schedule`: Schedules a push upgrade for an unlocked or second-generation managed package.
    * `package push-upgrade abort`: Cancels a push upgrade request.
    * `package push-upgrade list`: Displays the status of all push upgrade requests for a specific package..
    * `package push-upgrade report`: Displays detailed information for a specific push upgrade request.

    Push upgrades let you upgrade unlocked or second-generation managed packages installed in orgs, without asking customers to install the upgrade themselves.

    This example schedules a push upgrade that initiates at a specified time, and provides a list of org IDs to receive the package upgrade.

    ```bash
    sf package push-upgrade schedule --package 04txyz --start-time "2024-12-06T21:00:00" --org-list 00DAxx, 00DBx
    ```

* FIX: Decomposed workflows now play nice with other metadata in your DX project when deploying to an org. (GitHub issue [#3275](https://github.com/forcedotcom/cli/issues/3275), source-deploy-retrieve PR [#1571](https://github.com/forcedotcom/source-deploy-retrieve/pull/1571))

## 2.92.7 (June 11, 2027)

* NEW: The `package convert` command is now generally available. Package migrations let you convert an existing first-generation (1GP) package into a second-generation (2GP) package, and then migrate the 1GP package installed in subscriber orgs to 2GP. This example converts the latest managed-released version of the 1GP package with the specified package ID and gives it the installation key "password123"; the example uses the default Dev Hub org:
 
   ```bash
   sf package convert --package 033... --installation-key password123
   ```
  
* NEW: The `agent generate template` command is now generally available. Use this command to generate an agent template from an existing agent in your DX project so you can then package the template in a managed package. For example:

    ```bash
    sf agent generate template --agent-file force-app/main/default/bots/My_Agent/My_Agent.bot-meta.xml --agent-version 1
    ```

    (plugin-agent PR [#152](https://github.com/salesforcecli/plugin-agent/pull/152))

* CHANGE: We converted the plugin that contains the `agent` commands ([`plugin-agent`](https://github.com/salesforcecli/plugin-agent)) from JIT to core. As a result, starting with this release, new installs of Salesforce CLI automatically include the plugin.  (cli PR [#2254](https://github.com/salesforcecli/cli/pull/2254))

* FIX: Re-retrieving a custom object after adding a custom field using Salesforce UI now works correctly. (GitHub issues [#3300](https://github.com/forcedotcom/cli/issues/3300) and [#3301](https://github.com/forcedotcom/cli/issues/3301), plugin-deploy-retrieve PR [#1568](https://github.com/forcedotcom/source-deploy-retrieve/pull/1568))

## 2.91.6 (June 4, 2025)

* FIX: If you run a command that uses a SOAP API, such as `project deploy start`, and you have configured your connected app or external client app to issue JWT-based access tokens, the command now correctly fails and outputs an error message saying that the SOAP API doesn't support JWT-based access tokens.  (GitHub issue [#3297](https://github.com/forcedotcom/cli/issues/3297), jsforce PR [#1698](https://github.com/jsforce/jsforce/pull/1698))

* FIX: If you set the SF_ORG_METADATA_REST_DEPLOY environment variable or the `org-metadata-rest-deploy` configuration variable to `true`, then org settings in the scratch org definition file are now deployed using the REST API instead of the default SOAP API. (sfdx-core PR [#1192](https://github.com/forcedotcom/sfdx-core/pull/1192))

## 2.90.4 (May 28, 2025)

* NEW: Enable Apex debug logging when you use the `agent preview` CLI command to converse with your agent with the new `--apex-debug` flag. For example:

    ```bash
    sf agent preview --api-name "Resort_Manager" --target-org my-org --connected-app-user my-agent-user --apex-debug
    ```

    With this new flag, when any conversation message executes Apex code, a new Apex debug log file is written to the specified output directory, along with the transcript and response JSON files.  See [Debug Apex Code](https://developer.salesforce.com/docs/platform/sfvscode-extensions/guide/apex-debugging.html) in the _Salesforce Extensions for Visual Studio Code_ guide for information about using these debug log files. (plugin-agent PR [#141](https://github.com/salesforcecli/plugin-agent/pull/141))
  
* FIX: When you run `project deploy start` with the `--verbose` flag, and also set the CI environment variable to `true`, the command output now includes the `Test Success` section, same as the human-readable output.  (GitHub issue [#3291](https://github.com/forcedotcom/cli/issues/3291), GitHub discussion [#3242](https://github.com/forcedotcom/cli/discussions/3242), plugin-deploy-retrieve PR [#1358](https://github.com/salesforcecli/plugin-deploy-retrieve/pull/1358))

* FIX: We updated the directory name of the PricingRecipe metadata type in the [CLI registry](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json) to the correct `pricingRecipe`. (source-deploy-retrieve PR [#1565](https://github.com/forcedotcom/source-deploy-retrieve/pull/1565))

## 2.89.8 (May 21, 2025)

ANNOUNCEMENT: Agentforce DX is now generally available (GA)!  Check out the [Build Agents with Agentforce DX](https://developer.salesforce.com/docs/einstein/genai/guide/agent-dx.html) documentation in the _Agentforce Developer Guide_.  Enjoy!

-----------------

* CHANGE: The `org open agent` command is now generally available; previously it was beta. Also, to maintain consistency across all agent-related commands, we changed the `--name` flag name to `--api-name`. For example, to open the agent with API name `Coral_Cloud_Agent` in your default org using your default browser, run this command:

    ```bash
    sf org open agent --api-name Coral_Cloud_Agent
    ```

   (plugin-org PR [#1420](https://github.com/salesforcecli/plugin-org/pull/1420))

* CHANGE: The `agent preview` command is now beta; previously it was developer preview. (plugin-agent PR [#140](https://github.com/salesforcecli/plugin-agent/pull/140))

* FIX: Salesforce DX projects now support these [metadata types](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json):

    * DgtAssetMgmtProvider
    * DgtAssetMgmtPrvdLghtCpnt

    (GitHub issue [#3277](https://github.com/forcedotcom/cli/issues/3277), source-deploy-retrieve PR [#1561](https://github.com/forcedotcom/source-deploy-retrieve/pull/1561))

## 2.88.6 (May 14, 2025)

* CHANGE: We're excited to announce that these `agent` commands are now generally available; previously they were beta.

    * `agent create` : Create an agent in your org using a local agent spec file.
    * `agent generate agent-spec` : Generate an agent spec, which is a YAML file that captures what an agent can do.
    * `agent generate test-spec` : Generate an agent test spec, which is a YAML file that lists the test cases for testing a specific agent.
    * `agent test create` : Create an agent test in your org using a local test spec YAML file.
    * `agent test list` : List the available agent tests in your org.
    * `agent test results` : Get the results of a completed agent test run.
    * `agent test resume` : Resume an agent test that you previously started in your org so you can view the test results.
    * `agent test run` : Start an agent test in your org.

    The `agent generate template` command is still beta and the `agent preview` command is still developer preview.
  
    Also, to maintain consistency across all `agent` comamnds, we changed these flag names:

    * Command `agent create`:
       * The `--agent-api-name` flag is now `--api-name`.
       * The `--agent-name` flag is now `--name`.
    * Command `agent test create`
       * The `--test-api-name` flag is now `--api-name`.

  For example, to create an agent:

  ```bash
  sf agent create --name "Resort Manager" --api-name Resort_Manager --spec specs/resortManagerAgent.yaml --target-org my-org
  ```

  To create an agent test:

  ```bash
  sf agent test create --spec specs/Resort_Manager-testSpec.yaml --api-name Resort_Manager_Test --force-overwrite --target-org my-org
  ```

  (plugin-agent PR [#135](https://github.com/salesforcecli/plugin-agent/pull/135))

* FIX: Decomposing a permission set that grants access to multiple objects is now working correctly and as documented. (GitHub issue [#3233](https://github.com/forcedotcom/cli/issues/3233), source-deploy-retrieve PR [#1554](https://github.com/forcedotcom/source-deploy-retrieve/pull/1554))


## 2.87.7 (May 7, 2025)

* CHANGE: As we announced on [January 8, 2025](./README.md#2716-january-8-2025), we removed the `--bulk`, `--wait`, and `--async` flags of the `data query` command. We also removed the `data query resume` command.  Use the `data export bulk|resume` commands instead. For example:

    ```bash
    sf data export bulk --query "SELECT Id, Name, Account.Name FROM Contact" --output-file export-accounts.csv --wait 10 --target-org my-scratch
    ```

   (plugin-data PR [#1237](https://github.com/salesforcecli/plugin-data/pull/1237))

* FIX: We improved the help for `project retrieve start` by adding an example that shows how to use a wildcard to retrieve metadata components associated with a parent component, in this case list views for the Case standard object. It's not always obvious how to do this. (GitHub issue [#3266](https://github.com/forcedotcom/cli/issues/3266), plugin-deploy-retrieve [#1341](https://github.com/salesforcecli/plugin-deploy-retrieve/pull/1341))

## 2.86.9 (April 30, 2025)

* NEW: When refreshing a sandbox org with the `org refresh sandbox` command, you can now use the new `--source-id` or `--source-sandbox-name` flags to change its original source org to a new org. The refreshed sandbox org's metadata is then updated with the new source org's metadata. For example, this command refreshes the sandbox named `devSbx2` by changing its original source org to be a sandbox called `devSbx3`:

    ```bash
    sf org refresh sandbox --name devSbx2 --source-sandbox-name devSbx3 --target-org prodOrg
    ```

    The value of `--source-id` and `--source-sandbox-name` must be an existing sandbox. The new source sandbox org, and the refreshed sandbox specified with the `--name` flag, must both be associated with the production org (`--target-org`) that contains the sandbox licenses. You can specify either `--source-id `or `--source-sandbox-name` when refreshing an existing sandbox, but not both.

  We also updated a related issue where specifying the new source sandbox in a sandbox definition file with the `sourceSandboxName` option returned an error when running `org refresh sandbox`. (GitHub issue [#3262](https://github.com/forcedotcom/cli/issues/3262), plugin-auth PR [#1396](https://github.com/salesforcecli/plugin-org/pull/1396))

* NEW: The [Agentforce DX](./README.md#2794-march-12-2025) commands, such as `agent create` and `agent test run` are now just-in-time (JIT). This means that when you update to this Salesforce CLI release and run an `agent` command, Salesforce CLI checks if the associated [plugin-agent](https://github.com/salesforcecli/plugin-agent) is installed. If it's not, Salesforce CLI automatically installs it and then runs your command. (cli PR [#2203](https://github.com/salesforcecli/cli/pull/2203))

* NEW: Run flow tests in your org with these new CLI commands, which are contained in the just-in-time (JIT) [plugin-flow](https://github.com/salesforcecli/plugin-flow) plugin:

    * `flow run test` : Invoke flow tests in an org.   
    * `flow get test` : Display test results for a specific asynchronous test run.

    For example, this command runs all the tests associated with a flow in the org with alias `scratchOrg`; use the flow definition developer name to identify a flow:

    ```bash
    sf flow run test --target-org scratchOrg --class-names <flow defintion developer name>
    ```
    Run the two commands with the `--help` flag to get more information and examples.
  
    The `plugin-flow` plugin isn't included in the core Salesforce CLI; instead, it's installed the first time you run one of its commands.  

* FIX: You can now correctly retrieve DigitalExperienceBundle metadata components with the `project retrieve start` command into a DX project that already contains these components.  Previously you either got an error or they were retrieved into an incorrect directory. (source-deploy-retrieve PR [#1546](https://github.com/forcedotcom/source-deploy-retrieve/pull/1546)

* FIX: Salesforce CLI now displays a warning when you run `org logout` on an org that you haven't authorized; previously it incorrectly displayed a success message.

    **NOTE**: Starting September 2025, the new warning will be converted to an error. As a result, the exit code when you try to log out of an unauthenticated org will change from 0 to 1. (GitHub issue [#3247](https://github.com/forcedotcom/cli/issues/3247), plugin-org PR [#1282](https://github.com/salesforcecli/plugin-auth/pull/1282))

* FIX: Salesforce DX projects now support the WorkflowFlowAutomation [metadata type](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json). (GitHub issue [#3202](https://github.com/forcedotcom/cli/issues/3202))

## 2.85.7 (April 23, 2025)

* CHANGE: Starting with this release, the `--async` flag of these commands is deprecated because the commands are asynchronous by default:

    * `data delete bulk`
    * `data export bulk`
    * `data import bulk`
    * `data query`
    * `data update bulk`
    * `data upset bulk`

    (plugin-data PR [#1222](https://github.com/salesforcecli/plugin-data/pull/1222))

* CHANGE: Over the next few releases we'll be changing our licenses from the [3-Clause BSD License](https://opensource.org/license/bsd-3-clause) to the [Apache License, Version 2.0](https://opensource.org/license/apache-2-0). (dev-scripts PR [#386](https://github.com/forcedotcom/dev-scripts/pull/386))

## 2.84.6 (April 16, 2025)

* NEW: If the `org create scratch` command times out before the scratch org is ready, you run the `org resume scratch` command to poll for completion and see the results. You can now specify how long the command waits before it returns control of the terminal to you with the new `--wait` flag; the output shows the progress of the scratch org create. Previously you had to keep running the `org resume scratch` command until the scratch org was ready. In this example the command waits for 10 minutes before returning control to you:

    ```bash
    sf org resume scratch --job-id 2SRfakefake000345 --wait 10
    ```

    (plugin-org PR [#1376](https://github.com/salesforcecli/plugin-org/pull/1376), sfdx-core PR [#1177](https://github.com/forcedotcom/sfdx-core/pull/1177))

* FIX: When used with metadata types that are always in a folder, the `--exclude-metadata` flag of `project generate manifest --from-org` now correctly excludes both the metadata components and their folders. Examples of metadata type that are always in folders include [Document](https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_document.htm) and [Report](https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_report.htm).  (GitHub issue [#3232](https://github.com/forcedotcom/cli/issues/3232), source-deploy-retrieve PR [#1535](https://github.com/forcedotcom/source-deploy-retrieve/pull/1535))

* FIX: The `plugins discover` CLI command is now working as expected. (GitHub issue [#3238](https://github.com/forcedotcom/cli/issues/3238), plugin-marketplace PR [#457](https://github.com/salesforcecli/plugin-marketplace/pull/457))

* FIX: You can now correctly deploy and retrieve [CustomPermission](https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_custompermission.htm) metadata components while also decomposing the custom permissions in the [PermissionSet](https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_permissionset.htm) component. (GitHub issue [#3220](https://github.com/forcedotcom/cli/issues/3220), source-deploy-retrieve PR [1534x](https://github.com/forcedotcom/source-deploy-retrieve/pull/1534))


## 2.83.7 (April 9, 2025)

* FIX: Salesforce DX projects now support these [metadata types](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json):

    * FieldServiceMobileConfig
    * GenAiPlannerBundle

## 2.82.6 (April 2, 2025)

* FIX: We improved the displayed error message when a problem occurs while authorizing an org, such as a keychain file has the wrong permissions. (GitHub issue [#3231](https://github.com/forcedotcom/cli/issues/3231), sfdx-core PR [#1175](https://github.com/forcedotcom/sfdx-core/pull/1175))

* FIX: When specifying flag values in a file and using `--flags-dir` to pass the flag values to a command, files that contain multiple lines can now correctly use both LF and CRLF line endings.  (GitHub issue [#3236](https://github.com/forcedotcom/cli/issues/3236), cli PR [#2162](https://github.com/salesforcecli/cli/pull/2162))

## 2.81.9 (March 26, 2025)

* CHANGE: We removed the deprecated `--verbose` flag of `data delete bulk` and `data upsert bulk`; use the `data bulk results` command instead.  In October 2024 we deprecated the flag and added the deprecation warning in the command output. (plugin-data PR [#1206](https://github.com/salesforcecli/plugin-data/pull/1206))

* CHANGE: We no longer include the records that failed after running `data delete|upsert bulk --json` in the JSON output; use the `data bulk results` command to get this information.  We also removed the ability to resume synchronous data operations with the `data delete|upsert resume` commands.  In October 2024 we deprecated both of these features and added the deprecation warning in the command outputs. (plugin-data PR [#1209](https://github.com/salesforcecli/plugin-data/pull/1209))

* CHANGE: When you open an org in a browser with the `org open` command but without `--json` or `--url-only`, Salesforce CLI now generates a single-use frontdoor URL. This URL can be used one time only; subsequent use won't allow you to log into the org. This change makes the access to your org more secure.

    Code Builder users: when you run `org open` without `--json` or `--url-only` in a Code Builder terminal, the URL to open an org in a browser is displayed, rather than a browser automatically starting; this is normal expected behavior. The new change in Code Builder behavior is that the outputted URL is now single-use only and expires in 60 seconds. 

    Starting in August 2025, the generated URLs in the output of `org open --json` or `org open --url-only` will also be single-use only; until then the URLs continue to be multi-use.  A warning is printed if you use the `--json` or `--url-only` flags of `org open` to remind you of the upcoming change.  To immediately force the URLs in _all_ output of `org open` to be single-use, set the new SF_SINGLE_USE_ORG_OPEN_URL environment variable to `true`. For example:

    ```bash
    export SF_SINGLE_USE_ORG_OPEN_URL=true
    ```

    (GitHub issue [#2769](https://github.com/forcedotcom/cli/issues/2769), plugin-org PR [#1375](https://github.com/salesforcecli/plugin-org/pull/1375))

* FIX: We improved the error message returned when you run the `apex run test` command but there are no Apex tests in your org; it now clearly states what the problem is. (GitHub issue [#3217](https://github.com/forcedotcom/cli/issues/3217), plugin-apex PR [#706](https://github.com/salesforcecli/plugin-apex/pull/706))

* FIX: We fixed the remaining bugs around the `Maximum call stack size exceeded` error that sometimes occurred when running `project generate manifest --from-org` on an org that has more than 1,000 folder metadata components, such as `ReportFolder` or `DashboardFolder`. (plugin-deploy-retrieve PR [#1314](https://github.com/salesforcecli/plugin-deploy-retrieve/pull/1314), source-deploy-retrieve PR [#1526](https://github.com/forcedotcom/source-deploy-retrieve/pull/1526))

## 2.80.12 (March 19, 2025)

* NEW: Easily create a scratch org from a snapshot with the new `--snapshot` flag of `org create scratch`. Snapshots are a point-in-time copy of a scratch org which you create with the `org create snapshot` command. With this new flag, you're no longer required to create a definition file when creating a scratch org from a snapshot.

    For example, let's say you previously created a snapshot called `NightlyBranch`. To create a new scratch org using this snapshot, run this command: 

   ```bash
   sf org create scratch --alias my-scratch-org --target-dev-hub MyHub --snapshot NightlyBranch --wait 10
   ```
   
  In the example, the `MyHub` Dev Hub org must be associated with the `NightlyBranch` snapshot. We recommend you increase the wait time with the `--wait` flag because creating a scratch org from a snapshot can take a while. (plugin-org PR [#1358](https://github.com/salesforcecli/plugin-org/pull/1358))


* FIX: The `project generate manifest --from-org` command now runs successfully on orgs with over 100,000 metadata components. Previously, this command would result in an `Out of Memory` error.

    Additionally, to address issues with large numbers of folder metadata components, such as `EmailTemplateFolder`, we have set the default value of the `SF_LIST_METADATA_BATCH_SIZE` environment variable to `500`. This ensures the command completes correctly even when an org has more than 1,000 folder metadata components. Previously, the command would hang in such cases, even if the total number of components was less than 100,000. (GitHub issue [#3197](https://github.com/forcedotcom/cli/issues/3197), source-deploy-retrieve PR [#1511](https://github.com/forcedotcom/source-deploy-retrieve/pull/1511))

* FIX: The `org login web` command now gracefully returns an error if you use the `--browser` flag to specify a browser that isn't installed on your computer; previously the command would hang indefinitely. (GitHub issue [#1830](https://github.com/forcedotcom/cli/issues/1830), plugin-auth PR [#1260](https://github.com/salesforcecli/plugin-auth/pull/1260))

* FIX: Salesforce DX projects now support these [metadata types](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json):

  * DataObjectBuildOrgTemplate
  * InvocableActionExtension
  * LifeSciConfigCategory
  * LifeSciConfigRecord

## 2.79.4 (March 12, 2025)

* NEW: (BETA) We’re thrilled to announce the beta release of Agentforce DX, a set of new Salesforce CLI commands and a Visual Studio Code (VS Code) extension that let you create, preview, and test agents directly in a Salesforce DX project. With Agentforce DX you can:

    * **Generate YAML Spec Files**—Use the `agent generate agent-spec|test-spec` CLI commands to generate simple YAML spec files that describe agents and agent tests.
    * **Create Agents and Agent Tests**—Pass these spec files as inputs to the `agent create` and `agent test create` CLI commands to create agents and agent tests in your development org.
    * **Run Agent Tests**—Execute agent tests in your org and view the results from either the VS Code testing panel or by running the `agent test run|results|resume|list` CLI commands.
    * **Interact with Active Agents**—Interact directly with active agents using the `agent preview` CLI command. (Developer Preview)

    The new CLI commands are in the `agent` topic and are part of the [`@salesforce/plugin-agent`](https://github.com/salesforcecli/plugin-agent) plugin.  Install the plugin with this command:

    ```bash
    sf plugins install agent
    ```

    Download and install the VS Code Agentforce DX extension from the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-agents) or the [Open VSX Registry](https://open-vsx.org/extension/salesforce/salesforcedx-vscode-agents).

    Here are a few examples of what you can do with Agentforce DX.

    Generate an agent spec file that describes your new agent by providing some properties at the command line and be prompted for others; use your default org:

    ```bash
    sf agent generate agent-spec --type customer \
          --role "Field customer complaints and manage employee schedules."  \
          --output-file specs/resortManagerAgent.yaml
    ```

    Create the agent in your org by passing in the generated spec file:

    ```bash
    sf agent create --agent-name "Resort Manager" --spec specs/resortManagerAgent.yaml
    ```

    Generate an agent test spec for testing this new agent; this command is interactive and prompts you for all the information:

    ```bash
    sf agent generate test-spec
    ```

    Create an agent test in your org by passing in the generated test spec file:

    ```bash
    sf agent test create --spec specs/Resort_Manager-testSpec.yaml
    ```

    Run the agent test in your org:

    ```bash
    sf agent test run --api-name Resort_Manager_Test
    ```

    For more information, see:

    * [_Agentforce Developer Guide_: Agentforce DX](https://developer.salesforce.com/docs/einstein/genai/guide/agent-dx.html)
    * [_Salesforce CLI Command Reference_: agent Commands](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_agent_commands_unified.htm)

    We hope you enjoy these fun new commands!
    
    Known Issue: When generating the list of topics in an agent spec, the LLM sometimes includes dashes or other special characters in the topic names. These characters cause errors when creating an agent with the spec. Workaround: Be sure to use only underscores or alphanumeric characters in the topic names; spaces are fine.
      
## March 5, 2025

Due to [TDX 2025](https://www.salesforce.com/tdx/), we aren't releasing a new stable or stable-rc version today. Hope to see you at the conference!

## 2.78.3 (Feb 26, 2025)

* NEW: When you run `project deploy start` with both `--test-level` and `--verbose`, the human-readable output now shows how long each Apex test took to run, in milliseconds. This information was already available in the JSON output. Here's sample output:

    ```bash
    Test Success [11]
    ✓ GeocodingServiceTest.blankAddress (159ms)
    ✓ FileUtilitiesTest.createFileFailsWhenIncorrectBase64Data (263ms)
    ✓ FileUtilitiesTest.createFileFailsWhenIncorrectFilename (227ms)
    ✓ FileUtilitiesTest.createFileFailsWhenIncorrectRecordId (481ms)
    ```
    (GitHub discussion [#3194](https://github.com/forcedotcom/cli/discussions/3194), plugin-deploy-retrieve [#1286](https://github.com/salesforcecli/plugin-deploy-retrieve/pull/1286))

* FIX: The `project retrieve start --output-dir mydir` command now correctly writes single-file metadata components, such as GlobalValueSet, directly to the `mydir` directory; previously the command would incorrectly write them to `mydir/main/default`. (GitHub issue [#3177](https://github.com/forcedotcom/cli/issues/3177), plugin-deploy-retrieve PR [#1289](https://github.com/salesforcecli/plugin-deploy-retrieve/pull/1289))

* FIX: Salesforce DX projects now support these [metadata types](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json):

  * ContentTypeBundle
  * AnalyticsDashboard

## 2.77.6 (Feb 19, 2025)

* NEW: When generating a manifest with the `project generate manifest` command, you can now use the `--metadata` flag together with `--source-dir` to target specific metadata components in your local package directory.  This new feature is useful when you have multiple package directories or multiple directories within a single package directory and you want to target specific metadata within a source path.

  Similarly, you can also use `--excluded-metadata` with `--source-dir` to target all metadata in your local package directory _except_ the specified components. This example generates a manifest from the metadata components in the `force-app` package directory but excludes StandardValueSet components:

    ```bash
    sf project generate manifest --excluded-metadata StandardValueSet --source-dir force-app
    ``` 
    (plugin-deploy-retrieve PR [#1280](https://github.com/salesforcecli/plugin-deploy-retrieve/pull/1280))

* FIX: All commands that run Apex tests, such as `project deploy start`, now correctly display the test failures in both human output and when run in continuous integration (CI) jobs. (plugin-deploy-retrieve PR [#1284](https://github.com/salesforcecli/plugin-deploy-retrieve/pull/1284))

* FIX: DigitalExperience metadata components are now retrieved into multiple package directories as expected in all scenarios. (source-deploy-retrieve PR [#1496](https://github.com/forcedotcom/source-deploy-retrieve/pull/1496))

* FIX: Salesforce DX projects now correctly support the existing GenAiFunction bundle [metadata type](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json). (GitHub issue [#3204](https://github.com/forcedotcom/cli/issues/3204), source-deploy-retrieve PR [1499](https://github.com/forcedotcom/source-deploy-retrieve/pull/1499))

* FIX: Salesforce DX projects now support the AnnotationExtensionSet [metadata type](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json).

## 2.76.7 (Feb 12, 2025)

* FIX: Piping the output of a Salesforce CLI command that produces very wide tables is now working correctly. (GitHub issue [#3206](https://github.com/forcedotcom/cli/issues/3206), oclif PR [#93](https://github.com/oclif/table/pull/93))

## 2.75.5 (Feb 5, 2025)

* NEW: (Beta) You can now decompose the [ExternalServiceRegistration](https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_externalserviceregistration.htm) metadata component into two source files when you retrieve it to your Salesforce DX project, rather than retrieve a single monolithic metadata API format XML file. When you deploy to your org, the two files are re-converted into the one metadata API XML file.  For example, let's say the name of your ExternalServiceRegistration metadata component `BankService`. The two source files after decomposition are:

  * `BankService.yaml` : A YAML file that contains the contents of the `schema` field. If the field's content is in JSON format in your org, it's always converted to YAML format when retrieved to your DX project.
  * `BankService.externalServiceRegistration-meta.xml` : A standard metadata API XML file that contains all the fields _except_ `schema`.  

  Decomposing ExternalServiceRegistration metadata components is optional, so you must explicitly specify the behavior by running this command:
  
    ```bash
    sf project convert source-behavior --behavior decomposeExternalServiceRegistrationBeta
    ```
   When the `project convert source-behavior` command finishes, your `sfdx-project.json` file is updated to always decompose ExternalServiceRegistration components. The existing source files in your local package directories are converted into the new decomposed format and you can deploy and retrieve your metadata as usual. To preview what the command does without making any changes, specify the `--dry-run` flag.

  See [Start Decomposing the Optional Metadata Types (Beta)](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_ws_decomposed_md_types.htm) for more information.  The documentation will soon be updated with details about how ExternalServiceRegistration components are decomposed. (source-deploy-retrieve PR [#1493](https://github.com/forcedotcom/source-deploy-retrieve/pull/1493), plugin-deploy-retrieve PR [#1275](https://github.com/salesforcecli/plugin-deploy-retrieve/pull/1275))
  
* CHANGE: On January 31, 2025, Salesforce will retire Salesforce Functions, also known as Salesforce Elastic Services. See [Salesforce Functions Retirement](https://devcenter.heroku.com/articles/salesforce-functions-retirement) for more information. As a result, Salesforce CLI no longer JIT-installs the Salesforce Functions plugins (`plugin-env` and `plugin-functions`) and the Salesforce Functions commands, such as `run function start` aren't available by default.  If you need these commands, you must install the [`plugins-functions`](https://github.com/salesforcecli/plugin-functions) and [`plugins-env`](https://github.com/salesforcecli/plugin-env) plugins manually using the `plugins install` command. 

    We'll also soon remove the associated Salesforce Functions commands from the current version of the [Salesforce CLI Command Reference](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_functions_commands_unified.htm). If you need online reference information about the Salesforce Functions commands, see the [Winter '25 Salesforce CLI Command Reference](https://developer.salesforce.com/docs/atlas.en-us.252.0.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_functions_commands_unified.htm). (cli PR [#2093](https://github.com/salesforcecli/cli/pull/2093))

* FIX: The `force data bulk upsert` command now works correctly when upserting 10K+ records synchronously (specify the `--wait` flag) and using Node.js v22 or greater. (GitHub issue [#3180](https://github.com/forcedotcom/cli/issues/3180), plugin-data PR [#1172](https://github.com/salesforcecli/plugin-data/pull/1172))

* FIX: Salesforce DX projects now support the LightningTypeBundle [metadata type](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json).

## 2.74.6 (Jan 29, 2025)

* FIX: The `api request rest` command now correctly refreshes the access token if it has expired. (GitHub issue [#3176](https://github.com/forcedotcom/cli/issues/3176), sfdx-core PR [#1163](https://github.com/forcedotcom/sfdx-core/pull/1163), plugin-api PR [#62](https://github.com/salesforcecli/plugin-api/pull/62))

* FIX: If you run the `org create scratch` command with the `--json` flag, and the creation of the scratch org times out, its job ID is now included in the JSON output of the CLI command.  (plugin-org PR [#1317](https://github.com/salesforcecli/plugin-org/pull/1317))

* FIX: If you installed Salesforce CLI on Windows using the installer, you no longer get the message that starts `(node:9801) [DEP0040] DeprecationWarning: The punycode module is deprecated.` when you run any CLI command.  (GitHub issue [#3161](https://github.com/forcedotcom/cli/issues/3161), oclif PR [#1672](https://github.com/oclif/oclif/pull/1672))

## 2.73.9 (Jan 22, 2025)

* NEW: Ensure that your code adheres to best practices with these Code Analyzer v5 (Beta) commands in the just-in-time (JIT) `code-analyzer` plugin:

    * `code-analyzer config` :  Display the current state of configuration for Code Analyzer.
    * `code-analyzer rules` : List the rules that are available to analyze your code.
    * `code-analyzer run`  :  Analyze your code with a selection of rules to ensure good coding practices.

   The `code-analyzer` plugin isn't included in the core Salesforce CLI; instead, it's now installed the first time you run one of its commands. 

   The Code Analyzer v4 commands, such as `scanner run`, are also JIT and continue to work the same as before. Because the v4 and v5 commands are in separate CLI topics and plugins, they don't interfere with each other. We will stop JIT'ing the v4 `scanner` commands in the future, after the `code-analyzer` commands are generally available. 
  
    See the [Salesforce Code Analzyer v5 (Beta)](https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/guide/code-analyzer.html) documentation for more information about how to use these new v5 commands to identify problems earlier in your development process. 

* FIX: When you opt to [decompose sharing rules](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_ws_decomposed_md_types.htm), you can now deploy its children (such as SharingCriteriaRule) individually, rather than having to deploy the entire [SharingRules](https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_sharingrules.htm) component with all its children. (source-deploy-retrieve PR [#1482](https://github.com/forcedotcom/source-deploy-retrieve/pull/1482))

* FIX: When you start decomposing permission sets by running the `project convert source-behavior --behavior decomposePermissionSetBeta2` command and retrieving the permission set from the org, and the permission set contains custom permissions, the corresponding XML file (`PermSetName.customPermissions-meta.xml`) is now valid. (GitHub issue [#3165](https://github.com/forcedotcom/cli/issues/3165), source-deploy-retrieve PR [#1483](https://github.com/forcedotcom/source-deploy-retrieve/pull/1483))

* FIX: You can now correctly retrieve metadata components whose types have non-unique suffixes. For example, both `RestrictionRule` and `ModerationRule` have the `.rule` suffix.  (GitHub issue [#3168](https://github.com/forcedotcom/cli/issues/3168), source-deploy-retrieve PR [#1480](https://github.com/forcedotcom/source-deploy-retrieve/pull/1480))

* FIX: The `project deploy start` command now correctly returns an error when you specify a manifest with a typo for the `--manifest` flag and also specify the `--post|pre-destructive-changes` flags. (source-deploy-retrieve PR [#1481](https://github.com/forcedotcom/source-deploy-retrieve/pull/1481))

* FIX: Non-admin scratch org users can now successfully run `org display` when they specify their username for `--target-org`. (plugin-org PR [#1481](https://github.com/forcedotcom/source-deploy-retrieve/pull/1481))

* FIX: Salesforce DX projects now support these [metadata types](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json):

  * AnalyticsVisualization
  * AnalyticsVizViewDef
  * AnalyticsWorkspace

## 2.72.21 (Jan 15, 2025)

* NEW: When generating a manifest from the metadata components in an org by running the `project generate manifest --from-org` command, you can now specify the metadata components you **don't** want to include with the new `--excluded-metadata` flag. For example, this command generates a manifest of all the metadata components except StandardValueSet from the org with alias `my-org`:

    ```bash
    sf project generate manifest --from-org my-org --excluded-metadata StandardValueSet
    ```
    Use the existing `--metadata` flag with `--from-org` to specify the metadata components that you want to include in your manifest. For example:

    ```bash
    sf project generate manifest --from-org my-org --metadata ApexClass --metadata CustomObject
    ```
    **Tip**: If your list of included or excluded metadata components is long, consider using `--flags-dir` to [specify the components in a file](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_flag_values_in_files.htm) rather than at the command-line. 

    The `project generate manifest` command makes many concurrent API calls to discover the metadata that exists when generating a manifest from an org. To limit the number of concurrent requests, use the new SF_LIST_METADATA_BATCH_SIZE environment variable and set it to a size that works best for your org and environment. For example, to limit the number of concurrent API calls to 20:

  ```bash
  export SF_LIST_METADATA_BATCH_SIZE=20
  ```
  If you experience timeouts or inconsistent manifest contents, then setting this environment variable can improve accuracy. However, the command takes longer to run because it sends fewer requests at a time.

  (plugin-deploy-retrieve PR [#1247](https://github.com/salesforcecli/plugin-deploy-retrieve/pull/1247), source-deploy-retrieve PR [#1469](https://github.com/forcedotcom/source-deploy-retrieve/pull/1469))

* CHANGE: As we announced on [July 10, 2024](./README.md#2497-july-10-2024), we removed these two hidden commands:
  * `data import legacy tree` 
  * `data export legacy tree`

   Use `data import|export tree` instead. (plugin-data PR [#1116](https://github.com/salesforcecli/plugin-data/pull/1116))

* FIX: The WorkFlowAction child metadata type of Workflow is now correctly decomposed into its own subdirectory in your DX project when you opt to [decompose workflows](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_ws_decomposed_md_types.htm). Additionally, you can now deploy children of the [Workflow](https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_workflow.htm) metadata type (such as WorkFlowAction) individually, rather than having to deploy the entire Workflow with all its children. 

   Many thanks to [Matt Carvin](https://github.com/mcarvin8) for finding the bug, and then contributing the fix! We love your awesome initiative. (GitHub issue [#2563](https://github.com/forcedotcom/cli/issues/2563), source-deploy-retrieve PR [#1467](https://github.com/forcedotcom/source-deploy-retrieve/pull/1467))

* FIX: Salesforce DX projects now support these [metadata types](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json):

  * AiEvaluationDefinition
  * AiEvaluationTestSet
  * WorkflowFlowAction

## 2.71.6 (January 8, 2025)

* CHANGE: Starting this release, the `--bulk`, `--wait`, and `--async` flags of the `data query` command are deprecated. The `data query resume` command is also deprecated because it works with only the `data query` command in bulk mode. All these deprecated flags and command will be removed from Salesforce CLI on April 25, 2025, or later. Use the `data export bulk|resume` commands instead. For example:

    ```bash
    sf data export bulk --query "SELECT Id, Name, Account.Name FROM Contact" --output-file export-accounts.csv --wait 10 --target-org my-scratch
    ```

    (plugin-data PR [#1134](https://github.com/salesforcecli/plugin-data/pull/1134))

* FIX: We changed the running output of `project deploy start` to show test failures right away. As a result, you don’t need to wait for the entire deploy to finish before you decide how to handle the test failures. (GitHub issue [#3104](https://github.com/forcedotcom/cli/issues/3104), plugin-deploy-retrieve PR [#1215](https://github.com/salesforcecli/plugin-deploy-retrieve/pull/1215))

* FIX: The `data bulk` commands, when importing from a CSV file, default to the COMMA delimiter if they can't find the delimiter used in the CSV file. (plugin-data PR [#1151](https://github.com/salesforcecli/plugin-data/pull/1151))

* FIX: The `data import tree` command no longer fails when importing over 2K records. (GitHub [comment](https://github.com/forcedotcom/cli/issues/2738#issuecomment-2375750110), plugin-data PR [#1146](https://github.com/salesforcecli/plugin-data/pull/1146))

## December 25, 2024 AND January 1, 2025

Due to the holiday break, we aren't releasing a new stable version these two weeks. Happy holidays!

## 2.70.7 (December 18, 2024)

* NEW: Write the output of an executed SOQL query to a file with the new `--output-file` flag of the `data query` command. This new flag works only with CSV (comma-separated values) and JSON output, so you must use it in combination with `--result-format csv|json`. This example executes a SOQL query in an org with alias `my-scratch` and writes the JSON results to a file called `query-output.json`:

    ```bash
    sf data query --query "SELECT Id, Name, Account.Name FROM Contact" --output-file query-output.json --result-format json --target-org my-scratch
    ```

    (plugin-data PR [#1135](https://github.com/salesforcecli/plugin-data/pull/1135))

* FIX: The `org refresh|resume sandbox` commands no longer output the erroneous error `INSUFFICIENT_ACCESS: use of the Metadata API requires a user with the ModifyAllData or ModifyMetadata permissions​` after they finish executing. The error was incorrect because users who refresh or resume sandboxes don't need those permissions.  The refresh and resume of the sandbox always finished correctly, despite that error. (GitHub issue [#3048](https://github.com/forcedotcom/cli/issues/3048), plugin-org PR [#1276](https://github.com/salesforcecli/plugin-org/pull/1276))

* FIX: The `data export bulk` command no longer fails when exporting a very large dataset, such as millions of records, to a JSON-formatted output file. (GitHub issue [#3138](https://github.com/forcedotcom/cli/issues/3138), plugin-data PR [#1140](https://github.com/salesforcecli/plugin-data/pull/1140))

## 2.69.14 (December 11, 2024)

* NEW: Specify the line endings used in the comma-separated values (CSV) file when you run the `data delete|upsert bulk` commands with the new `--line-ending` flag. The default value on Windows is `CRLF`; on macOS and Linux it's `LF`. Similarly, specify the column delimiters in the CSV file when you run `data upsert bulk` with the new `--column-delimiter` flag; possible values include `BACKQUOTE`, `CARET`, and more. For example:

    ```bash
    sf data upsert bulk --sobject Contact --file contacts.csv --external-id Id --line-ending LF --column-delimiter CARET
    ```

    (GitHub discussion #[2947](https://github.com/forcedotcom/cli/discussions/2947), plugin-data PR [#1110](https://github.com/salesforcecli/plugin-data/pull/1110))

* FIX: Salesforce CLI no longer outputs the message that starts `(node:9801) [DEP0040] DeprecationWarning: The `punycode` module is deprecated.` when you're using Node.js v22 or greater and you run any CLI command.  (GitHub issue [#2535](https://github.com/forcedotcom/cli/issues/2535), salesforce/cli PR [#1971](https://github.com/salesforcecli/cli/pull/1971))

## 2.68.6 (December 4, 2024)

* NEW: (BETA) Open an agent in the Agent Builder UI with the new `open org agent` command.  Use the `--name` flag to open an agent using its API name.  For example:

    ```bash
    sf open org agent --name Coral_Cloud_Agent
    ```

  To find the agent's API name, go to Setup in your org and navigate to the agent's details page.  (plugin-org PR [#1264](https://github.com/salesforcecli/plugin-org/pull/1264))

* FIX: We improved the table output when `project deploy start` fails due to an metadata validation error.  We now provide the name of the metadata type that's causing the error in the `Type` column. (GitHub issue [#3110](https://github.com/forcedotcom/cli/issues/3110), plugin-deploy-retrieve PR [#1217](https://github.com/salesforcecli/plugin-deploy-retrieve/pull/1217))

* FIX: If you set your `target-org` configuration variable to a sandbox, and then run `org delete scratch` without specifying the `--target-org` flag, the command now returns an error. Previously the command would delete the sandbox. (GitHub issue [#3058](https://github.com/forcedotcom/cli/issues/3058), plugin-org PR [#1257](https://github.com/salesforcecli/plugin-org/pull/1257))

## Nov 27, 2024

Due to the Thanksgiving break in the United States, we aren't releasing a new stable version. Happy Thanksgiving!

## 2.67.7 (November 20, 2024)

* FIX: We updated the `--help` of `apex test run` to say that users who run the command must have the View All Data system permission. (plugin-apex PR [#630](https://github.com/salesforcecli/plugin-apex/pull/630))

## 2.66.7 (November 13, 2024)

* NEW: Bulk update many records of a Salesforce object from a comma-separated values (CSV) file with the new `data update bulk` command.

   All the records in the CSV file must be for the same Salesforce object and the first column of every line must be an ID of the record you want to update. The CSV file can contain only existing records; if a record in the file doesn't currently exist in the Salesforce object, the command fails. Use the `--sobject` flag to specify the Salesforce object. See [Prepare Data to Ingest](https://developer.salesforce.com/docs/atlas.en-us.api_asynch.meta/api_asynch/datafiles_prepare_data.htm) in the "Bulk API 2.0 and Bulk API Developer Guide" for details about creating the CSV file.

    For example, this command updates Account records from the `accounts.csv` file in an org with alias "my-scratch":
    ```bash
    sf data update bulk --file accounts.csv --sobject Account --wait 10 --target-org my-scratch
    ```
   Bulk updates can take a while, depending on how many records are in the CSV file. If the command times out after the specified wait time (10 minutes in our example), it displays a job ID that you then pass to the new `data update resume` command to see the status and results of the original update. For example:

    ```bash
    sf data update resume --job-id 750xx000fake005sAAA
    ```
    (plugin-data PR [#1098](https://github.com/salesforcecli/plugin-data/pull/1098))


* NEW: Get the results of a previously run and completed bulk ingest (import, update, upsert, or delete) job with the new `data bulk results` command. The command works for jobs executed with Bulk API 2.0, such as a CLI command like `data import bulk` or an external tool like Data Loader, as long as the job provides a job ID. Pass the job ID to `data bulk results` to retrieve the results.

    The command displays information such as the job status, the ingest operation, updated Salesforce object, how many records were processed, and how many failed or succeeded. Finally, the output displays the names of the generated CSV-formatted files that contain the specific results for each ingested record. For example:

    ```bash
    sf data bulk results --job-id 7507i000fake341G --target-org my-scratch
    ```
    (GitHub discussion [#2387](https://github.com/forcedotcom/cli/discussions/2387), plugin-data PR [#1097](https://github.com/salesforcecli/plugin-data/pull/1097))

* NEW: Specify the ID of the sandbox you want to clone with the new `--source-id` flag of the `org create sandbox` command. We also added a similar new option `sourceId` to the sandbox definition file.  As always, the flag takes precendence if you specify both. This example shows how to clone an existing sandbox with ID `
Download .txt
gitextract_q88b20da/

├── .git2gus/
│   └── config.json
├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── config.yml
│   ├── actions/
│   │   ├── new-issue/
│   │   │   ├── action.yml
│   │   │   ├── lib/
│   │   │   │   ├── index.d.ts
│   │   │   │   └── index.js
│   │   │   ├── src/
│   │   │   │   └── index.ts
│   │   │   └── tsconfig.json
│   │   └── validate-issue/
│   │       ├── action.yml
│   │       ├── lib/
│   │       │   ├── index.d.ts
│   │       │   ├── index.js
│   │       │   ├── nodeVersions.d.ts
│   │       │   └── nodeVersions.js
│   │       ├── messages/
│   │       │   ├── deprecated-cli.md
│   │       │   ├── old-cli.md
│   │       │   ├── provide-version.md
│   │       │   └── unsupported-node.md
│   │       ├── mock/
│   │       │   └── sample-context.json
│   │       ├── src/
│   │       │   ├── index.ts
│   │       │   └── nodeVersions.ts
│   │       └── tsconfig.json
│   └── workflows/
│       ├── closeStaleIssues.yml
│       ├── issue-updated.yml
│       └── new-label.yml
├── .gitignore
├── CHANGELOG.md
├── CODEOWNERS
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── README.md
├── SECURITY.md
├── package.json
├── releasenotes/
│   ├── README.md
│   ├── sf/
│   │   └── README.md
│   ├── sfdx/
│   │   ├── README.md
│   │   ├── v41.md
│   │   ├── v42.md
│   │   ├── v43.md
│   │   ├── v44.md
│   │   ├── v45.md
│   │   ├── v46.md
│   │   ├── v47.md
│   │   ├── v48.md
│   │   ├── v49.md
│   │   └── v50.md
│   ├── v49.md
│   └── v50.md
└── tsconfig.json
Download .txt
SYMBOL INDEX (5 symbols across 5 files)

FILE: .github/actions/new-issue/lib/index.js
  function run (line 20) | async function run() {

FILE: .github/actions/new-issue/src/index.ts
  function run (line 20) | async function run() {

FILE: .github/actions/validate-issue/lib/index.js
  function run (line 26) | async function run() {

FILE: .github/actions/validate-issue/src/index.ts
  function run (line 25) | async function run() {

FILE: .github/actions/validate-issue/src/nodeVersions.ts
  type VersionInfo (line 17) | type VersionInfo = {
Condensed preview — 50 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (903K chars).
[
  {
    "path": ".git2gus/config.json",
    "chars": 406,
    "preview": "{\n  \"productTag\": \"a1aB00000004Bx8IAE\",\n  \"productTagLabels\": { \"area:afdx\": \"a1aEE000001vDZRYA2\" },\n  \"defaultBuild\": \""
  },
  {
    "path": ".gitattributes",
    "chars": 49,
    "preview": ".github/actions/**/lib/* linguist-generated=true\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 1657,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: 'investigating'\nassignees: ''\n\n---\n> **"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 360,
    "preview": "blank_issues_enabled: false\ncontact_links:\n  - name: Salesforce DX Community\n    url: https://success.salesforce.com/iss"
  },
  {
    "path": ".github/actions/new-issue/action.yml",
    "chars": 438,
    "preview": "name: \"Salesforce CLI Issues Bot\"\ndescription: \"Preform automatic responses to github issues.\"\nauthor: \"Lisa Morgan\"\ninp"
  },
  {
    "path": ".github/actions/new-issue/lib/index.d.ts",
    "chars": 11,
    "preview": "export {};\n"
  },
  {
    "path": ".github/actions/new-issue/lib/index.js",
    "chars": 3394,
    "preview": "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/*\n * Copyright 2025, Salesforce, Inc.\n *\n "
  },
  {
    "path": ".github/actions/new-issue/src/index.ts",
    "chars": 3020,
    "preview": "/*\n * Copyright 2025, Salesforce, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": ".github/actions/new-issue/tsconfig.json",
    "chars": 137,
    "preview": "{\n  \"extends\": \"@salesforce/dev-config/tsconfig-strict\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\"\n  },\n  \"files\": [\""
  },
  {
    "path": ".github/actions/validate-issue/action.yml",
    "chars": 272,
    "preview": "name: \"Salesforce CLI Validate Issues\"\ndescription: \"Validate information provided in an new Github issue.\"\nauthor: \"Eri"
  },
  {
    "path": ".github/actions/validate-issue/lib/index.d.ts",
    "chars": 11,
    "preview": "export {};\n"
  },
  {
    "path": ".github/actions/validate-issue/lib/index.js",
    "chars": 10260,
    "preview": "\"use strict\";\n/*\n * Copyright 2025, Salesforce, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\""
  },
  {
    "path": ".github/actions/validate-issue/lib/nodeVersions.d.ts",
    "chars": 105,
    "preview": "export declare const isAnyVersionValid: (currentDate: Date) => (versions: string[]) => Promise<boolean>;\n"
  },
  {
    "path": ".github/actions/validate-issue/lib/nodeVersions.js",
    "chars": 1239,
    "preview": "\"use strict\";\n/*\n * Copyright 2025, Salesforce, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\""
  },
  {
    "path": ".github/actions/validate-issue/messages/deprecated-cli.md",
    "chars": 537,
    "preview": "Hello @THE_AUTHOR :wave:\n\nIt looks like you're using an outdated version of Salesforce CLI. OLD_CLI is in \"maintenance m"
  },
  {
    "path": ".github/actions/validate-issue/messages/old-cli.md",
    "chars": 601,
    "preview": "Hello @THE_AUTHOR :wave: None of the versions of `USER_CLI` you shared match the latest release.\n\nShared: `USER_VERSION`"
  },
  {
    "path": ".github/actions/validate-issue/messages/provide-version.md",
    "chars": 843,
    "preview": "Hello @THE_AUTHOR :wave: It looks like you didn't include the full Salesforce CLI version information in your issue.\nPle"
  },
  {
    "path": ".github/actions/validate-issue/messages/unsupported-node.md",
    "chars": 381,
    "preview": "Hello @THE_AUTHOR :wave: Your version of nodeJS (`NODE_VERSION`) is not supported.\n\nWe recommend using LTS and we suppor"
  },
  {
    "path": ".github/actions/validate-issue/mock/sample-context.json",
    "chars": 2713,
    "preview": "{\n  \"active_lock_reason\": null,\n  \"assignee\": null,\n  \"assignees\": [],\n  \"author_association\": \"OWNER\",\n  \"body\": \"@sale"
  },
  {
    "path": ".github/actions/validate-issue/src/index.ts",
    "chars": 8866,
    "preview": "/*\n * Copyright 2025, Salesforce, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": ".github/actions/validate-issue/src/nodeVersions.ts",
    "chars": 1211,
    "preview": "/*\n * Copyright 2025, Salesforce, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": ".github/actions/validate-issue/tsconfig.json",
    "chars": 160,
    "preview": "{\n  \"extends\": \"@salesforce/dev-config/tsconfig-strict\",\n  \"compilerOptions\": {\n    \"outDir\": \"./lib\",\n    \"lib\": [\"ES20"
  },
  {
    "path": ".github/workflows/closeStaleIssues.yml",
    "chars": 604,
    "preview": "name: Close Stale Issues\npermissions:\n  issues: write\non:\n  workflow_dispatch:\n  schedule:\n    - cron: '30 1 * * *'\n\njob"
  },
  {
    "path": ".github/workflows/issue-updated.yml",
    "chars": 1088,
    "preview": "name: \"validate-updated-issue\"\non:\n  issues:\n    types: [edited]\n  issue_comment:\n    types: [created, edited]\n\njobs:\n  "
  },
  {
    "path": ".github/workflows/new-label.yml",
    "chars": 4606,
    "preview": "name: \"new-label\"\non: # any labels added to an issue\n  issues:\n    types: [labeled]\n\njobs:\n  owned-by-other-team:\n    if"
  },
  {
    "path": ".gitignore",
    "chars": 522,
    "preview": "# Dependency directory\nnode_modules\n\n# Rest pulled from https://github.com/github/gitignore/blob/master/Node.gitignore\n#"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 97,
    "preview": "Changelog can be found here: https://github.com/forcedotcom/cli/blob/main/releasenotes/README.md\n"
  },
  {
    "path": "CODEOWNERS",
    "chars": 272,
    "preview": "# Technical writers will be added as reviewers on markdown changes.\n*.md @forcedotcom/cli-docs\n\n# Comment line immediate"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 5155,
    "preview": "# Salesforce Open Source Community Code of Conduct\n\n## About the Code of Conduct\n\nEquality is a core value at Salesforce"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 4699,
    "preview": "# Contributing to the Salesforce CLI\nWelcome, and thank you for your interest in contributing to the Salesforce CLI!\n\nTh"
  },
  {
    "path": "LICENSE.txt",
    "chars": 11444,
    "preview": "Apache License Version 2.0\n\nCopyright (c) 2025 Salesforce, Inc.\nAll rights reserved.\n\n                                 A"
  },
  {
    "path": "README.md",
    "chars": 3484,
    "preview": "# Description\n\nThis is an issue-only repository for Salesforce CLI. We monitor this repo for feedback from the community"
  },
  {
    "path": "SECURITY.md",
    "chars": 401,
    "preview": "## Security\n\nPlease report any security issue to [security@salesforce.com](mailto:security@salesforce.com)\nas soon as it"
  },
  {
    "path": "package.json",
    "chars": 988,
    "preview": "{\n  \"name\": \"cli\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Issues Only repository for the community to submit feedback, "
  },
  {
    "path": "releasenotes/README.md",
    "chars": 297934,
    "preview": "# Salesforce CLI Release Notes\n\nHere are the new and changed features in recent updates of Salesforce CLI.\n\nWe publish a"
  },
  {
    "path": "releasenotes/sf/README.md",
    "chars": 115985,
    "preview": "# Salesforce CLI Release Notes (sf Commands)\n\n**IMPORTANT ANNOUNCEMENT, PLEASE READ**: We no longer update `sf` (v1); th"
  },
  {
    "path": "releasenotes/sfdx/README.md",
    "chars": 258133,
    "preview": "# Salesforce CLI Release Notes (sfdx Commands)\n\n**IMPORTANT ANNOUNCEMENT, PLEASE READ**: We no longer update `sfdx` (v7)"
  },
  {
    "path": "releasenotes/sfdx/v41.md",
    "chars": 6807,
    "preview": "# Salesforce CLI v41 Release Notes\n\nHere are the new and changed features in recent updates of the Salesforce CLI and th"
  },
  {
    "path": "releasenotes/sfdx/v42.md",
    "chars": 12276,
    "preview": "# Salesforce DX CLI v42 Release Notes\n\nHere are the new and changed features in recent updates of the Salesforce CLI and"
  },
  {
    "path": "releasenotes/sfdx/v43.md",
    "chars": 13252,
    "preview": "# Salesforce CLI v43 Release Notes\n\nHere are the new and changed features in recent updates of the Salesforce CLI and th"
  },
  {
    "path": "releasenotes/sfdx/v44.md",
    "chars": 13955,
    "preview": "# Salesforce CLI v44 Release Notes\n\nHere are the new and changed features in recent updates of the Salesforce CLI and th"
  },
  {
    "path": "releasenotes/sfdx/v45.md",
    "chars": 16725,
    "preview": "# Salesforce CLI v45 Release Notes\n\nHere are the new and changed features in recent updates of Salesforce CLI and the `s"
  },
  {
    "path": "releasenotes/sfdx/v46.md",
    "chars": 14146,
    "preview": "# Salesforce CLI v46 Release Notes\n\nHere are the new and changed features in recent updates of Salesforce CLI and the `s"
  },
  {
    "path": "releasenotes/sfdx/v47.md",
    "chars": 13707,
    "preview": "# Salesforce CLI v47 Release Notes\n\nHere are the new and changed features in recent updates of Salesforce CLI and the `s"
  },
  {
    "path": "releasenotes/sfdx/v48.md",
    "chars": 15105,
    "preview": "# Salesforce CLI v48 Release Notes\n\nHere are the new and changed features in recent updates of Salesforce CLI and the `s"
  },
  {
    "path": "releasenotes/sfdx/v49.md",
    "chars": 20448,
    "preview": "# Salesforce CLI v49 Release Notes\n\nHere are the new and changed features in recent updates of Salesforce CLI and the `s"
  },
  {
    "path": "releasenotes/sfdx/v50.md",
    "chars": 16777,
    "preview": "# Salesforce CLI v50 Release Notes\n\nHere are the new and changed features in recent updates of Salesforce CLI and the `s"
  },
  {
    "path": "releasenotes/v49.md",
    "chars": 98,
    "preview": "# Salesforce CLI v49 Release Notes\n\nThis file has moved. [Here's the new location](sfdx/v49.md). \n"
  },
  {
    "path": "releasenotes/v50.md",
    "chars": 98,
    "preview": "# Salesforce CLI v50 Release Notes\n\nThis file has moved. [Here's the new location](sfdx/v50.md). \n"
  },
  {
    "path": "tsconfig.json",
    "chars": 139,
    "preview": "{\n  \"files\": [],\n  \"references\": [\n    { \"path\": \"./.github/actions/new-issue\" },\n    { \"path\": \"./.github/actions/valid"
  }
]

About this extraction

This page contains the full source code of the forcedotcom/cli GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 50 files (864.9 KB), approximately 223.2k tokens, and a symbol index with 5 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!