Migrate `build/commands` code to ESM to allow `.js`/`.ts` imports to work correctly in any direction. This allows for gradual migration to `.ts` while keeping `.js` files around.
Few notes on migration:
1. `import.meta.*` cannot be used reliably with Jest. I tried different versions and approaches, eventually came up with a `.cjs` module that still uses `__dirName`, but can be imported into ESM and CommonJS modules without issues. I also considered rewriting Jest tests into built-in Node test runner, but since I was able to make Jest work, this was abandoned.
2. `tsc` accepts both `file.js`/`file.ts` in imports and passes a compiler check without errors, but Node requires an import of a real file (type stripping is based on a file type). This means an incorrect import will pass `test:scripts`, but fail on real execution (see [related discussion](https://github.com/microsoft/TypeScript/issues/61021)). An eslint rule was added to enforce that.
3. local `require()` calls replaced with async/global imports depending on context.