Unfortunately, the CLI will always pull "Remote Add" metadata (ie. metadata not previously seen in any local SFDX Package Directory) into
main/default/<metadata-type> inside of the default Package Directory specified in your project's
From the CLI's point of view, this behavior is by design. You need to have a place where previously unseen metadata can go, and
<default-package-dir>/main/default provides that.
The part that needs fixing is the fact that the CLI is treating your subsequent reorganization (move) of your SFDX source files as a series of "Local Deletes" and "Local Adds" instead of just a simple "Local Moves".
Safe Harbor: The SFDX team is aware of this bug and is working on a fix. There is no ETA for when such a fix will be delivered. I'll update this answer once an ETA is available.
In the meantime, there are two ways you could work around this.
Workaround 1: Create a "local starter", push to scratch org, then customize in Setup UI
Technically, you can create your own metadata files locally and then do an initial push to your scratch org, even for those types that are more complex in SFDX, like
Take a look at how an existing metadata type (object, permset, profile, etc.) is stored as SFDX source, copy that, then customize it as necessary for your new metadata component.
This isn't an elegant solution, but it does have the benefit of getting you comfortable with editing metadata files. For anyone who hasn't done this, it can be intimidating at first but you end up feeling like Neo seeing the Matrix once you've done it a few times. ;-)
Workaround 2: Build in Setup UI, reorganize locally in bulk, then rebuild your scratch org
You mentioned that you're aware of the SFDX-Falcon template. One of the things I like about SFDX-Falcon is the set of shell scripts provided in the
dev-tools directory. They give a head start to anyone who wants to automate Salesforce CLI actions, and the one I use the most is
If you know you're going to add a couple of custom objects and fields to your project, go ahead and build them in the Setup UI, pulling as you go without worrying about where the metadata is getting stored locally.
Once you're done with all the changes, open up a GUI file explorer and drag things out of
<default-package-dir>/main/default and drop them wherever you want (as long as your destination is inside of an SFDX package directory).
rebuild-scratch-orgs shell script (which you've hopefully customized so that it does everything you need for a full scratch org build), and you'll be good to go. The CLI will know where everything is supposed to be from that point forward.
Closing Point: Is organizing my source worth all the trouble?
I definitely understand the frustration at not being able to fine-tune where new "Remote Add" metadata is saved by default. I still think it's worth the effort to come up with some logical structure that goes beyond the basic
force-app/main/default that we get by default.
Your solution might not look exactly like SFDX-Falcon, but it's a good idea to do something, especially for projects based on large enterprise implementations and AppExchange packages.