I Moved 90% of My Salesforce Work Into the CLI and IDE. Here's What Broke.

A practical Salesforce workflow for using source, the CLI, and AI while keeping schema checks, reviews, and user verification intact.

The Apex class compiled. The unit tests passed. The field did not exist.

The API name looked right. Perfectly Salesforce-shaped. The model had invented a tiny piece of my org and written clean code around it. Honestly, that was useful.

The fix took less than a minute: check the object description, replace the invented name, rerun the test. The useful part was the reminder. Generated code can be syntactically perfect, locally green, and completely wrong about the system it is changing. Most demos skip that part.

Most of my Salesforce work has migrated out of Setup and into the CLI and an IDE. Apex, Lightning Web Components, metadata retrieval, deployments, SOQL, permission-set XML, test runs, code analysis: if it is source-shaped, I want it in a file. AI sits in that workflow now too. It can inspect a repository, write a class, run sf commands, read errors, and try again without making me copy output between five windows.

That setup is faster. It is also much easier to be wrong at scale.

The 90% is not time-sheet math. It means nearly all work that can be represented responsibly as metadata; though the ratio drops when I am deep in Flow Builder or testing access with a real user.

Typing less is useful, but the bigger win is that the work leaves a trail. The catch is that an assistant can sprint down that trail faster than I can review what it touched.

If it can be metadata, I want it in source control

Setup is good at showing the current state of one org. It is much worse at answering how that state changed, why it changed, and whether the same change exists anywhere else.

A field created in Object Manager exists. A field added as metadata in a repository has a history. I can review the XML, see the commit, compare branches, run checks, and deploy the same definition through environments. The same is true for Apex, LWC, permission sets, custom metadata, and most of the platform surface area that Salesforce exposes as metadata.

That is why I moved the work. Speed helped sell it. Reliability made it stick.

Salesforce’s Developer Experience center now puts the CLI, VS Code extensions, Git, scratch orgs, Code Analyzer, and AI tools in the same stack. That is a long way from Apex in an editor while everything else lived in Setup, screenshots, and somebody’s memory of last Tuesday.

The CLI makes the platform scriptable. The IDE makes the source navigable. Git makes the change reviewable. AI makes all three easier to operate, provided it has access to the actual repository and org output rather than a paragraph describing them.

None of this is free. Authentication, project structure, branches, and reviews all carry a cost. Pay it for repeatable team changes, not disposable experiments. Source-driven development is a control system, not a professional-identity test.

The loop I trust is boring

The version I trust does not begin with a heroic prompt. It is a loop:

  1. Inspect the target org and the repository before changing anything.
  2. Retrieve the relevant metadata or confirm the repository already has the current version.
  3. Index the metadata
  4. Make the smallest coherent change.
  5. Run static analysis and focused tests.
  6. Validate the deployment against the target org.
  7. Deploy, then inspect the result in the place where users experience it.

Commands, flags, deployment behavior, and required test levels vary by project and target org, but the shape stays stable. I might query data with sf data query, retrieve metadata with sf project retrieve start, run Apex tests with sf apex run test, and validate a deployment with sf project deploy validate. The exact flags matter less than the sequence. Context comes before generation. Validation comes before deployment. Verification comes after it.

Inside that loop, AI is useful. It traces references quickly, turns deployment errors into focused edits, generates test fixtures, and finds the command flag I would otherwise look up again.

It is especially good at work I refuse to pretend is intellectually rewarding: repetitive XML changes, scaffolding, reference renames, and the first implementation of a clear requirement.

That is also where trust starts to slip.

The schema is where confidence fails first

A Salesforce org has a vocabulary. Its words include object and field API names, record types, namespaces, picklist values, and relationships. An AI assistant trained on Salesforce knows the grammar of that vocabulary. It does not automatically know the words in your org.

If the prompt says “route enterprise opportunities by region,” it may write clean Apex around Opportunity.Region__c. That field name is plausible. It may even exist in another company’s org. Plausible is not the same as present.

A more elaborate prompt will not fix that. Grounding will. Give the assistant the retrieved metadata, object describe output, or a repository search. Make it prove that a referenced symbol exists before it writes code around it. Then make the compiler and tests prove the code works.

That changes where I spend my time. Less on the first version, more on the assumptions underneath it. I am fine with that. Checking assumptions was always the job. All the typing just made it easier to forget.

Git is authoritative only when the team keeps it current

Putting metadata in Git does not make Git authoritative by executive order.

Someone can still create a field in Object Manager. An admin can update a Flow in production during an incident. A permission can change through Setup. If those changes are not retrieved and reconciled, the org and the repository drift apart. The next deployment may overwrite a fix, resurrect an old configuration, or fail for reasons that look unrelated to the work in front of you.

AI makes this worse when it treats the repository as complete. It sees what is on disk and confidently reasons from an incomplete map. AI did not invent org drift, weak reviews, or undocumented production fixes. It lets those old failures travel faster and affect more files at once.

There is not a clever fix here. Decide which environments permit direct changes. Retrieve before editing when the source may be stale. Review deployment previews. Use source tracking where it applies, and use comparison tooling where it does not. If an emergency change happens in the UI, bringing it back into source control is part of the incident closeout, not an optional cleanup task.

The repository becomes authoritative when the team keeps the promise. The README is not magic.

Permission sets can make fast work expensive

Permission metadata looks harmless in a diff. A few XML entries. Maybe ten lines. Easy.

The consequences are not always friendly.

A generated permission-set change can grant object access without the expected field access, expose an Apex class while missing a required custom permission, or collide with assumptions spread across permission-set groups. The XML tells you what changed. It does not tell you the full effective access of the person receiving it.

I still use the CLI for permission work because I want the diff and repeatability. I also inspect the result in Salesforce and test with a representative user. No single XML file or Setup screen gives you the complete effective-access picture. A successful deployment proves that Salesforce accepted the metadata. It does not prove that the intended user can complete the intended task without gaining something else.

You have to test the consequence, preferably as the person who will live with it.

I still build Flow in Flow Builder

Flow metadata belongs in source control. Flow authoring still belongs, mostly, in Flow Builder.

An AI can modify Flow XML and still leave a technically valid graph that is miserable to maintain. Layout, labels, paths, screens, and debugging matter because Flow is a visual programming environment.

This is where I draw the line: retrieve, compare, deploy, and govern Flow through source-driven practices. Build and debug the visual behavior in Flow Builder. Use the IDE to understand the metadata and review changes, not to cosplay as a canvas.

Big adoption numbers are not code review

Salesforce reports that its internal CodeGenie system has produced more than 7 million lines of code accepted by developers, answered more than 500,000 developer questions, and saves more than 30,000 hours each month. It integrates across IDEs, GitHub, the CLI, portals, and Slack.

Those numbers tell me Salesforce is investing heavily and its developers are using the tools. They do not prove that every accepted line was correct, maintainable, or worth keeping. “Accepted” is an interaction metric. “Hours saved” is a vendor-reported estimate. Neither replaces defect rates, review quality, or business outcomes.

Salesforce’s separate research found that 96% of developers expected AI to improve the developer experience and more than four in five expected agents to become essential to app development. The research included more than 2,000 software-development leaders and a supplementary survey of nearly 250 frontline developers in the United States.

People expect this workflow to stick. Fine. I still have to read the diff.

A passing command is not the definition of done

Before AI, I could confuse effort with understanding. I wrote the code, so surely I understood it. That was never guaranteed, but the friction made the illusion comfortable.

Now the first draft may arrive in seconds. My definition of done has to be explicit:

  • Every referenced object, field, class, permission, and metadata type exists in the target context.
  • The diff contains only the intended change.
  • Focused tests cover success, failure, and permission behavior.
  • The target org accepts the deployment.
  • A human verifies the result through the surface the user will actually touch.
  • Emergency or UI changes are reconciled back into source.

I did not add that checklist because AI is spooky. We should have been this disciplined when humans wrote every line too. AI just removed the excuse that review would take longer than implementation.

Move the work. Keep the judgment.

I do not want to go back to doing most Salesforce work through Setup. The CLI and IDE give me a better record, a faster loop, and a development surface I can automate. AI removes enough repetitive work that I can spend more time on architecture, review, and the weird edge cases that actually deserve more than a decade of platform experience.

But I also do not want a workflow where green text in a terminal passes for truth.

Move the source-shaped work into files. Let AI help with the mechanical parts. Keep visual authoring where the visual tool is better. Ground every generated change in the real org, and verify the result where it will be used.

The terminal is my default now. Judgment is still the job.

Sources