Add OS suffix support for all tool properties

We had specific hardcoded support for OS-specific URLs.  This change makes that generic and allows `_windows` / `_linux` / `_mac` suffixes to work with any key.

This change is really a no-op that makes way to using a windows specific activated_path for now (allowing us to use the upstream windows node archive, rather than re-packaging/hacking it in (scripts/update_node.py).  See #1760.

Also:

- Remove support for `os: "all"`.. this is not used and doesn't seem useful (since you can just omit it).
- Remove support the `unix` urls.  This complexity (i.e. both unix and linux being valid suffixes) is not needed, since we can get the same behaviour by specifying `_windows` along with a generic url.
diff --git a/emsdk.py b/emsdk.py
index 436f701..7ced946 100644
--- a/emsdk.py
+++ b/emsdk.py
@@ -174,15 +174,24 @@
 KEEP_DOWNLOADS = get_env_boolean('EMSDK_KEEP_DOWNLOADS')
 
 
-def os_name():
+def os_name_short():
   if WINDOWS:
     return 'win'
   elif LINUX:
     return 'linux'
   elif MACOS:
     return 'mac'
-  else:
-    raise Exception('unknown OS')
+  assert False, 'unknown OS'
+
+
+def os_name():
+  if WINDOWS:
+    return 'windows'
+  if LINUX:
+    return 'linux'
+  if MACOS:
+    return 'macos'
+  assert False, 'unknown OS'
 
 
 def debug_print(msg):
@@ -1090,7 +1099,7 @@
   debug_print(f'build_llvm({tool})')
   llvm_root = tool.installation_path()
   llvm_src_root = os.path.join(llvm_root, 'src')
-  success = git_clone_checkout_and_pull(tool.download_url(), llvm_src_root, tool.git_branch)
+  success = git_clone_checkout_and_pull(tool.url, llvm_src_root, tool.git_branch)
   if not success:
     return False
 
@@ -1150,7 +1159,7 @@
   debug_print(f'build_ninja({tool})')
   root = os.path.normpath(tool.installation_path())
   src_root = os.path.join(root, 'src')
-  success = git_clone_checkout_and_pull(tool.download_url(), src_root, tool.git_branch)
+  success = git_clone_checkout_and_pull(tool.url, src_root, tool.git_branch)
   if not success:
     return False
 
@@ -1185,7 +1194,7 @@
   debug_print(f'build_ccache({tool})')
   root = os.path.normpath(tool.installation_path())
   src_root = os.path.join(root, 'src')
-  success = git_clone_checkout_and_pull(tool.download_url(), src_root, tool.git_branch)
+  success = git_clone_checkout_and_pull(tool.url, src_root, tool.git_branch)
   if not success:
     return False
 
@@ -1827,18 +1836,29 @@
   emscripten_releases_hash = None
   git_branch = None
   url = None
-  macos_url = None
-  linux_url = None
-  windows_url = None
 
   def __init__(self, data):
     self.uses = []
 
     # Convert the dictionary representation of the tool in 'data' to members of
-    # this class for convenience.
+    # this class. Base attributes are assigned first, then host OS-matching suffixed
+    # attributes (e.g. url_windows, activated_path_windows) are applied on top as overrides.
+    # Foreign OS keys are ignored.
+    os_overrides = {}
+    all_os_names = {'windows', 'macos', 'linux'}
+
     for key, value in data.items():
+      if '_' in key:
+        prefix, suffix = key.rsplit('_', 1)
+        if suffix in all_os_names:
+          if suffix == os_name():
+            os_overrides[prefix] = value
+          continue
       setattr(self, key, value)
 
+    for prefix, value in os_overrides.items():
+      setattr(self, prefix, value)
+
     # Cache the name ID of this Tool (these are read very often)
     self.name = self.id
     if self.version:
@@ -1939,24 +1959,8 @@
       return False
 
     if self.os:
-      assert self.os in {'all', 'linux', 'win', 'macos'}
-      if self.os == 'all':
-        return True
-      if (WINDOWS and self.os == 'win') or (LINUX and self.os == 'linux') or (MACOS and self.os == 'macos'):
-        return True
-      return False
-
-    if not any((self.macos_url, self.windows_url, self.linux_url)):
-      return True
-
-    if MACOS and self.macos_url:
-      return True
-
-    if LINUX and self.linux_url:
-      return True
-
-    if WINDOWS and self.windows_url:
-      return True
+      assert self.os in {'linux', 'windows', 'macos'}
+      return self.os == os_name()
 
     return self.url is not None
 
@@ -1990,7 +1994,7 @@
         if not tool.is_installed():
           return False
 
-    if self.download_url() is None:
+    if self.url is None:
       debug_print(f'{self} has no files to download, so is installed by default.')
       return True
 
@@ -2072,15 +2076,6 @@
         return "this tool is only provided for 64-bit OSes"
     return True
 
-  def download_url(self):
-    if WINDOWS and self.windows_url:
-      return self.windows_url
-    elif MACOS and self.macos_url:
-      return self.macos_url
-    elif LINUX and self.linux_url:
-      return self.linux_url
-    return self.url
-
   def install(self):
     """Returns True if the Tool was installed of False if was skipped due to
     already being installed.
@@ -2130,7 +2125,6 @@
       return False
 
     print(f"Installing tool '{self}'..")
-    url = self.download_url()
 
     custom_install_scripts = {
       'build_llvm': build_llvm,
@@ -2142,12 +2136,12 @@
     if self.custom_install_script in custom_install_scripts:
       success = custom_install_scripts[self.custom_install_script](self)
     elif self.git_branch:
-      success = git_clone_checkout_and_pull(url, self.installation_path(), self.git_branch, getattr(self, 'remote_name', 'origin'))
-    elif url.endswith(ARCHIVE_SUFFIXES):
-      success = download_and_extract(url, self.installation_path(),
+      success = git_clone_checkout_and_pull(self.url, self.installation_path(), self.git_branch, getattr(self, 'remote_name', 'origin'))
+    elif self.url.endswith(ARCHIVE_SUFFIXES):
+      success = download_and_extract(self.url, self.installation_path(),
                                      filename_prefix=getattr(self, 'download_prefix', ''))
     else:
-      assert False, 'unhandled url type: ' + url
+      assert False, 'unhandled url type: ' + self.url
 
     if not success:
       exit_with_error("installation failed!")
@@ -2190,9 +2184,8 @@
   def cleanup_temp_install_files(self):
     if KEEP_DOWNLOADS:
       return
-    url = self.download_url()
-    if url.endswith(ARCHIVE_SUFFIXES):
-      download_target = get_download_target(url, download_dir, getattr(self, 'download_prefix', ''))
+    if self.url.endswith(ARCHIVE_SUFFIXES):
+      download_target = get_download_target(self.url, download_dir, getattr(self, 'download_prefix', ''))
       debug_print(f"Deleting temporary download: {download_target}")
       rmfile(download_target)
 
@@ -2342,7 +2335,7 @@
 
   def make_url(ext):
    return emscripten_releases_download_url_template % (
-      os_name(),
+      os_name_short(),
       release,
       arch,
       ext,
diff --git a/emsdk_manifest.json b/emsdk_manifest.json
index b1f880f..af3ad3c 100644
--- a/emsdk_manifest.json
+++ b/emsdk_manifest.json
@@ -34,9 +34,9 @@
     "version": "%releases-tag%",
     "bitness": 64,
     "arch": "x86_64",
-    "linux_url": "https://storage.googleapis.com/webassembly/emscripten-releases-builds/linux/%releases-tag%/wasm-binaries.tar.xz",
-    "macos_url": "https://storage.googleapis.com/webassembly/emscripten-releases-builds/mac/%releases-tag%/wasm-binaries.tar.xz",
-    "windows_url": "https://storage.googleapis.com/webassembly/emscripten-releases-builds/win/%releases-tag%/wasm-binaries.zip",
+    "url_linux": "https://storage.googleapis.com/webassembly/emscripten-releases-builds/linux/%releases-tag%/wasm-binaries.tar.xz",
+    "url_macos": "https://storage.googleapis.com/webassembly/emscripten-releases-builds/mac/%releases-tag%/wasm-binaries.tar.xz",
+    "url_windows": "https://storage.googleapis.com/webassembly/emscripten-releases-builds/win/%releases-tag%/wasm-binaries.zip",
     "download_prefix": "%releases-tag%-",
     "install_path": "upstream",
     "activated_path": "%installation_dir%/emscripten",
@@ -48,8 +48,8 @@
     "version": "%releases-tag%",
     "bitness": 64,
     "arch": "arm64",
-    "macos_url": "https://storage.googleapis.com/webassembly/emscripten-releases-builds/mac/%releases-tag%/wasm-binaries-arm64.tar.xz",
-    "linux_url": "https://storage.googleapis.com/webassembly/emscripten-releases-builds/linux/%releases-tag%/wasm-binaries-arm64.tar.xz",
+    "url_macos": "https://storage.googleapis.com/webassembly/emscripten-releases-builds/mac/%releases-tag%/wasm-binaries-arm64.tar.xz",
+    "url_linux": "https://storage.googleapis.com/webassembly/emscripten-releases-builds/linux/%releases-tag%/wasm-binaries-arm64.tar.xz",
     "download_prefix": "%releases-tag%-",
     "install_path": "upstream",
     "activated_path": "%installation_dir%/emscripten",
@@ -62,7 +62,7 @@
     "version": "18.20.3",
     "bitness": 32,
     "arch": "x86",
-    "windows_url": "node-v18.20.3-win-x86.zip",
+    "url_windows": "node-v18.20.3-win-x86.zip",
     "activated_path": "%installation_dir%/bin",
     "activated_path_skip": "node",
     "activated_cfg": "NODE_JS='%installation_dir%/bin/node%.exe%'",
@@ -73,7 +73,7 @@
     "version": "18.20.3",
     "arch": "arm",
     "bitness": 32,
-    "linux_url": "node-v18.20.3-linux-armv7l.tar.xz",
+    "url_linux": "node-v18.20.3-linux-armv7l.tar.xz",
     "activated_path": "%installation_dir%/bin",
     "activated_path_skip": "node",
     "activated_cfg": "NODE_JS='%installation_dir%/bin/node%.exe%'",
@@ -84,9 +84,9 @@
     "version": "18.20.3",
     "bitness": 64,
     "arch": "x86_64",
-    "macos_url": "node-v18.20.3-darwin-x64.tar.gz",
-    "windows_url": "node-v18.20.3-win-x64.zip",
-    "linux_url": "node-v18.20.3-linux-x64.tar.xz",
+    "url_macos": "node-v18.20.3-darwin-x64.tar.gz",
+    "url_windows": "node-v18.20.3-win-x64.zip",
+    "url_linux": "node-v18.20.3-linux-x64.tar.xz",
     "activated_path": "%installation_dir%/bin",
     "activated_path_skip": "node",
     "activated_cfg": "NODE_JS='%installation_dir%/bin/node%.exe%'",
@@ -97,8 +97,8 @@
     "version": "18.20.3",
     "arch": "arm64",
     "bitness": 64,
-    "macos_url": "node-v18.20.3-darwin-arm64.tar.gz",
-    "linux_url": "node-v18.20.3-linux-arm64.tar.xz",
+    "url_macos": "node-v18.20.3-darwin-arm64.tar.gz",
+    "url_linux": "node-v18.20.3-linux-arm64.tar.xz",
     "activated_path": "%installation_dir%/bin",
     "activated_path_skip": "node",
     "activated_cfg": "NODE_JS='%installation_dir%/bin/node%.exe%'",
@@ -111,7 +111,7 @@
     "version": "20.18.0",
     "bitness": 32,
     "arch": "x86",
-    "windows_url": "node-v20.18.0-win-x86.zip",
+    "url_windows": "node-v20.18.0-win-x86.zip",
     "activated_path": "%installation_dir%/bin",
     "activated_path_skip": "node",
     "activated_cfg": "NODE_JS='%installation_dir%/bin/node%.exe%'",
@@ -122,7 +122,7 @@
     "version": "20.18.0",
     "arch": "arm",
     "bitness": 32,
-    "linux_url": "node-v20.18.0-linux-armv7l.tar.xz",
+    "url_linux": "node-v20.18.0-linux-armv7l.tar.xz",
     "activated_path": "%installation_dir%/bin",
     "activated_path_skip": "node",
     "activated_cfg": "NODE_JS='%installation_dir%/bin/node%.exe%'",
@@ -133,9 +133,9 @@
     "version": "20.18.0",
     "bitness": 64,
     "arch": "x86_64",
-    "macos_url": "node-v20.18.0-darwin-x64.tar.gz",
-    "windows_url": "node-v20.18.0-win-x64.zip",
-    "linux_url": "node-v20.18.0-linux-x64.tar.xz",
+    "url_macos": "node-v20.18.0-darwin-x64.tar.gz",
+    "url_windows": "node-v20.18.0-win-x64.zip",
+    "url_linux": "node-v20.18.0-linux-x64.tar.xz",
     "activated_path": "%installation_dir%/bin",
     "activated_path_skip": "node",
     "activated_cfg": "NODE_JS='%installation_dir%/bin/node%.exe%'",
@@ -146,9 +146,9 @@
     "version": "20.18.0",
     "arch": "arm64",
     "bitness": 64,
-    "windows_url": "node-v20.18.0-win-arm64.zip",
-    "macos_url": "node-v20.18.0-darwin-arm64.tar.gz",
-    "linux_url": "node-v20.18.0-linux-arm64.tar.xz",
+    "url_windows": "node-v20.18.0-win-arm64.zip",
+    "url_macos": "node-v20.18.0-darwin-arm64.tar.gz",
+    "url_linux": "node-v20.18.0-linux-arm64.tar.xz",
     "activated_path": "%installation_dir%/bin",
     "activated_path_skip": "node",
     "activated_cfg": "NODE_JS='%installation_dir%/bin/node%.exe%'",
@@ -161,7 +161,7 @@
     "version": "22.16.0",
     "bitness": 32,
     "arch": "x86",
-    "windows_url": "node-v22.16.0-win-x86.zip",
+    "url_windows": "node-v22.16.0-win-x86.zip",
     "activated_path": "%installation_dir%/bin",
     "activated_path_skip": "node",
     "activated_cfg": "NODE_JS='%installation_dir%/bin/node%.exe%'",
@@ -172,7 +172,7 @@
     "version": "22.16.0",
     "arch": "arm",
     "bitness": 32,
-    "linux_url": "node-v22.16.0-linux-armv7l.tar.xz",
+    "url_linux": "node-v22.16.0-linux-armv7l.tar.xz",
     "activated_path": "%installation_dir%/bin",
     "activated_path_skip": "node",
     "activated_cfg": "NODE_JS='%installation_dir%/bin/node%.exe%'",
@@ -183,9 +183,9 @@
     "version": "22.16.0",
     "bitness": 64,
     "arch": "x86_64",
-    "windows_url": "node-v22.16.0-win-x64.zip",
-    "macos_url": "node-v22.16.0-darwin-x64.tar.gz",
-    "linux_url": "node-v22.16.0-linux-x64.tar.xz",
+    "url_windows": "node-v22.16.0-win-x64.zip",
+    "url_macos": "node-v22.16.0-darwin-x64.tar.gz",
+    "url_linux": "node-v22.16.0-linux-x64.tar.xz",
     "activated_path": "%installation_dir%/bin",
     "activated_path_skip": "node",
     "activated_cfg": "NODE_JS='%installation_dir%/bin/node%.exe%'",
@@ -196,9 +196,9 @@
     "version": "22.16.0",
     "arch": "arm64",
     "bitness": 64,
-    "windows_url": "node-v22.16.0-win-arm64.zip",
-    "macos_url": "node-v22.16.0-darwin-arm64.tar.gz",
-    "linux_url": "node-v22.16.0-linux-arm64.tar.xz",
+    "url_windows": "node-v22.16.0-win-arm64.zip",
+    "url_macos": "node-v22.16.0-darwin-arm64.tar.gz",
+    "url_linux": "node-v22.16.0-linux-arm64.tar.xz",
     "activated_path": "%installation_dir%/bin",
     "activated_path_skip": "node",
     "activated_cfg": "NODE_JS='%installation_dir%/bin/node%.exe%'",
@@ -209,7 +209,7 @@
     "version": "22.16.0",
     "arch": "x86_64",
     "bitness": 64,
-    "linux_url": "https://nodejs.org/download/release/v22.16.0/node-v22.16.0-linux-s390x.tar.gz",
+    "url_linux": "https://nodejs.org/download/release/v22.16.0/node-v22.16.0-linux-s390x.tar.gz",
     "activated_path": "%installation_dir%/bin",
     "activated_path_skip": "node",
     "activated_cfg": "NODE_JS_TEST=['qemu-s390x', '-L', '/usr/s390x-linux-gnu/', '%installation_dir%/bin/node']"
@@ -220,9 +220,9 @@
     "version": "24.7.0",
     "bitness": 64,
     "arch": "x86_64",
-    "windows_url": "node-v24.7.0-win-x64.zip",
-    "macos_url": "node-v24.7.0-darwin-x64.tar.gz",
-    "linux_url": "node-v24.7.0-linux-x64.tar.xz",
+    "url_windows": "node-v24.7.0-win-x64.zip",
+    "url_macos": "node-v24.7.0-darwin-x64.tar.gz",
+    "url_linux": "node-v24.7.0-linux-x64.tar.xz",
     "activated_path": "%installation_dir%/bin",
     "activated_path_skip": "node",
     "activated_cfg": "NODE_JS='%installation_dir%/bin/node%.exe%'",
@@ -233,9 +233,9 @@
     "version": "24.7.0",
     "arch": "arm64",
     "bitness": 64,
-    "windows_url": "node-v24.7.0-win-arm64.zip",
-    "macos_url": "node-v24.7.0-darwin-arm64.tar.gz",
-    "linux_url": "node-v24.7.0-linux-arm64.tar.xz",
+    "url_windows": "node-v24.7.0-win-arm64.zip",
+    "url_macos": "node-v24.7.0-darwin-arm64.tar.gz",
+    "url_linux": "node-v24.7.0-linux-arm64.tar.xz",
     "activated_path": "%installation_dir%/bin",
     "activated_path_skip": "node",
     "activated_cfg": "NODE_JS='%installation_dir%/bin/node%.exe%'",
@@ -246,7 +246,7 @@
     "version": "24.7.0",
     "arch": "x86_64",
     "bitness": 64,
-    "linux_url": "node-v24.7.0-linux-s390x.tar.gz",
+    "url_linux": "node-v24.7.0-linux-s390x.tar.gz",
     "activated_path": "%installation_dir%/bin",
     "activated_path_skip": "node",
     "activated_cfg": "NODE_JS_TEST=['qemu-s390x', '-L', '/usr/s390x-linux-gnu/', '%installation_dir%/bin/node']"
@@ -274,8 +274,8 @@
     "arch": "x86_64",
     "activated_cfg": "EMSDK_CMAKE='%installation_dir%/bin/cmake%.exe%'",
     "activated_path": "%installation_dir%/bin",
-    "windows_url": "https://github.com/Kitware/CMake/releases/download/v4.2.0-rc3/cmake-4.2.0-rc3-windows-x86_64.zip",
-    "linux_url": "https://github.com/Kitware/CMake/releases/download/v4.2.0-rc3/cmake-4.2.0-rc3-linux-x86_64.tar.gz"
+    "url_windows": "https://github.com/Kitware/CMake/releases/download/v4.2.0-rc3/cmake-4.2.0-rc3-windows-x86_64.zip",
+    "url_linux": "https://github.com/Kitware/CMake/releases/download/v4.2.0-rc3/cmake-4.2.0-rc3-linux-x86_64.tar.gz"
   },
   {
     "id": "cmake",
@@ -284,7 +284,7 @@
     "arch": "x86_64",
     "activated_cfg": "EMSDK_CMAKE='%installation_dir%/CMake.app/Contents/bin/cmake%.exe%'",
     "activated_path": "%installation_dir%/CMake.app/Contents/bin",
-    "macos_url": "https://github.com/Kitware/CMake/releases/download/v4.2.0-rc3/cmake-4.2.0-rc3-macos-universal.tar.gz"
+    "url_macos": "https://github.com/Kitware/CMake/releases/download/v4.2.0-rc3/cmake-4.2.0-rc3-macos-universal.tar.gz"
   },
   {
     "id": "cmake",
@@ -293,8 +293,8 @@
     "arch": "arm64",
     "activated_cfg": "EMSDK_CMAKE='%installation_dir%/bin/cmake%.exe%'",
     "activated_path": "%installation_dir%/bin",
-    "windows_url": "https://github.com/Kitware/CMake/releases/download/v4.2.0-rc3/cmake-4.2.0-rc3-windows-arm64.zip",
-    "linux_url": "https://github.com/Kitware/CMake/releases/download/v4.2.0-rc3/cmake-4.2.0-rc3-linux-aarch64.tar.gz"
+    "url_windows": "https://github.com/Kitware/CMake/releases/download/v4.2.0-rc3/cmake-4.2.0-rc3-windows-arm64.zip",
+    "url_linux": "https://github.com/Kitware/CMake/releases/download/v4.2.0-rc3/cmake-4.2.0-rc3-linux-aarch64.tar.gz"
   },
   {
     "id": "cmake",
@@ -303,7 +303,7 @@
     "arch": "arm64",
     "activated_cfg": "EMSDK_CMAKE='%installation_dir%/CMake.app/Contents/bin/cmake%.exe%'",
     "activated_path": "%installation_dir%/CMake.app/Contents/bin",
-    "macos_url": "https://github.com/Kitware/CMake/releases/download/v4.2.0-rc3/cmake-4.2.0-rc3-macos-universal.tar.gz"
+    "url_macos": "https://github.com/Kitware/CMake/releases/download/v4.2.0-rc3/cmake-4.2.0-rc3-macos-universal.tar.gz"
   },
 
   {
@@ -311,7 +311,7 @@
     "version": "3.9.2-nuget",
     "bitness": 64,
     "arch": "x86_64",
-    "windows_url": "python-3.9.2-4-amd64+pywin32.zip",
+    "url_windows": "python-3.9.2-4-amd64+pywin32.zip",
     "activated_cfg": "PYTHON='%installation_dir%/python.exe'",
     "activated_env": "EMSDK_PYTHON=%installation_dir%/python.exe"
   },
@@ -320,7 +320,7 @@
     "version": "3.9.2",
     "bitness": 64,
     "arch": "x86_64",
-    "windows_url": "python-3.9.2-1-embed-amd64+pywin32.zip",
+    "url_windows": "python-3.9.2-1-embed-amd64+pywin32.zip",
     "activated_cfg": "PYTHON='%installation_dir%/python.exe'",
     "activated_env": "EMSDK_PYTHON=%installation_dir%/python.exe"
   },
@@ -329,7 +329,7 @@
     "version": "3.9.2",
     "bitness": 64,
     "arch": "x86_64",
-    "macos_url": "python-3.9.2-3-macos-x86_64.tar.gz",
+    "url_macos": "python-3.9.2-3-macos-x86_64.tar.gz",
     "activated_cfg": "PYTHON='%installation_dir%/bin/python3'",
     "activated_env": "EMSDK_PYTHON=%installation_dir%/bin/python3;SSL_CERT_FILE=%installation_dir%/lib/python3.9/site-packages/certifi/cacert.pem"
   },
@@ -338,7 +338,7 @@
     "version": "3.9.2",
     "bitness": 64,
     "arch": "arm64",
-    "macos_url": "python-3.9.2-1-macos-arm64.tar.gz",
+    "url_macos": "python-3.9.2-1-macos-arm64.tar.gz",
     "activated_cfg": "PYTHON='%installation_dir%/bin/python3'",
     "activated_env": "EMSDK_PYTHON=%installation_dir%/bin/python3;SSL_CERT_FILE=%installation_dir%/lib/python3.9/site-packages/certifi/cacert.pem"
   },
@@ -348,7 +348,7 @@
     "version": "3.13.3",
     "bitness": 64,
     "arch": "x86_64",
-    "windows_url": "python-3.13.3-0-win-amd64.zip",
+    "url_windows": "python-3.13.3-0-win-amd64.zip",
     "activated_cfg": "PYTHON='%installation_dir%/python.exe'",
     "activated_env": "EMSDK_PYTHON=%installation_dir%/python.exe"
   },
@@ -357,7 +357,7 @@
     "version": "3.13.3",
     "bitness": 64,
     "arch": "arm64",
-    "windows_url": "python-3.13.3-0-win-arm64.zip",
+    "url_windows": "python-3.13.3-0-win-arm64.zip",
     "activated_cfg": "PYTHON='%installation_dir%/python.exe'",
     "activated_env": "EMSDK_PYTHON=%installation_dir%/python.exe"
   },
@@ -366,7 +366,7 @@
     "version": "3.13.3",
     "bitness": 64,
     "arch": "x86_64",
-    "macos_url": "python-3.13.3-0-macos-x86_64.tar.gz",
+    "url_macos": "python-3.13.3-0-macos-x86_64.tar.gz",
     "activated_cfg": "PYTHON='%installation_dir%/bin/python3'",
     "activated_env": "EMSDK_PYTHON=%installation_dir%/bin/python3;SSL_CERT_FILE=%installation_dir%/lib/python3.13/site-packages/certifi/cacert.pem"
   },
@@ -375,7 +375,7 @@
     "version": "3.13.3",
     "bitness": 64,
     "arch": "arm64",
-    "macos_url": "python-3.13.3-0-macos-arm64.tar.gz",
+    "url_macos": "python-3.13.3-0-macos-arm64.tar.gz",
     "activated_cfg": "PYTHON='%installation_dir%/bin/python3'",
     "activated_env": "EMSDK_PYTHON=%installation_dir%/bin/python3;SSL_CERT_FILE=%installation_dir%/lib/python3.13/site-packages/certifi/cacert.pem"
   },
@@ -498,7 +498,7 @@
     "version": "tag-%tag%",
     "bitness": 32,
     "append_bitness": false,
-    "windows_url": "https://github.com/emscripten-core/emscripten/archive/%tag%.zip",
+    "url_windows": "https://github.com/emscripten-core/emscripten/archive/%tag%.zip",
     "url": "https://github.com/emscripten-core/emscripten/archive/%tag%.tar.gz",
     "download_prefix": "emscripten-e",
     "activated_cfg": "EMSCRIPTEN_ROOT='%installation_dir%'",
@@ -511,7 +511,7 @@
     "version": "tag-%tag%",
     "bitness": 64,
     "append_bitness": false,
-    "windows_url": "https://github.com/emscripten-core/emscripten/archive/%tag%.zip",
+    "url_windows": "https://github.com/emscripten-core/emscripten/archive/%tag%.zip",
     "url": "https://github.com/emscripten-core/emscripten/archive/%tag%.tar.gz",
     "activated_cfg": "EMSCRIPTEN_ROOT='%installation_dir%'",
     "activated_path": "%installation_dir%",
@@ -521,7 +521,7 @@
   {
     "id": "emscripten",
     "version": "%precompiled_tag%",
-    "windows_url": "https://github.com/emscripten-core/emscripten/archive/%precompiled_tag%.zip",
+    "url_windows": "https://github.com/emscripten-core/emscripten/archive/%precompiled_tag%.zip",
     "url": "https://github.com/emscripten-core/emscripten/archive/%precompiled_tag%.tar.gz",
     "activated_cfg": "EMSCRIPTEN_ROOT='%installation_dir%'",
     "activated_path": "%installation_dir%",
@@ -532,7 +532,7 @@
     "version": "tag-%binaryen_tag%",
     "bitness": 32,
     "append_bitness": false,
-    "windows_url": "https://github.com/WebAssembly/binaryen/archive/%binaryen_tag%.zip",
+    "url_windows": "https://github.com/WebAssembly/binaryen/archive/%binaryen_tag%.zip",
     "url": "https://github.com/WebAssembly/binaryen/archive/%binaryen_tag%.tar.gz",
     "download_prefix": "binaryen-e",
     "activated_cfg": "BINARYEN_ROOT='%installation_dir%%generator_prefix%_64bit_binaryen'",
@@ -548,7 +548,7 @@
     "version": "tag-%binaryen_tag%",
     "bitness": 64,
     "append_bitness": false,
-    "windows_url": "https://github.com/WebAssembly/binaryen/archive/%binaryen_tag%.zip",
+    "url_windows": "https://github.com/WebAssembly/binaryen/archive/%binaryen_tag%.zip",
     "url": "https://github.com/WebAssembly/binaryen/archive/%binaryen_tag%.tar.gz",
     "download_prefix": "binaryen-e",
     "activated_cfg": "BINARYEN_ROOT='%installation_dir%%generator_prefix%_64bit_binaryen'",
@@ -619,7 +619,7 @@
     "id": "mingw",
     "version": "7.1.0",
     "bitness": 64,
-    "windows_url": "mingw_7.1.0_64bit.zip",
+    "url_windows": "mingw_7.1.0_64bit.zip",
     "activated_cfg": "MINGW_ROOT='%installation_dir%'",
     "activated_path": "%installation_dir%/bin"
   },
@@ -627,9 +627,9 @@
     "id": "ninja",
     "version": "1.13.2",
     "bitness": 64,
-    "windows_url": "ninja-1.13.2-win-x64.zip",
-    "linux_url": "ninja-1.13.2-linux-x64.zip",
-    "macos_url": "ninja-1.13.2-mac.zip",
+    "url_windows": "ninja-1.13.2-win-x64.zip",
+    "url_linux": "ninja-1.13.2-linux-x64.zip",
+    "url_macos": "ninja-1.13.2-mac.zip",
     "arch": "x86_64",
     "activated_cfg": "NINJA_ROOT='%installation_dir%'",
     "activated_path": "%installation_dir%"
@@ -638,7 +638,7 @@
     "id": "ninja",
     "version": "1.13.2",
     "bitness": 64,
-    "macos_url": "ninja-1.13.2-mac.zip",
+    "url_macos": "ninja-1.13.2-mac.zip",
     "os": "macos",
     "arch": "arm64",
     "activated_cfg": "NINJA_ROOT='%installation_dir%'",
@@ -673,7 +673,7 @@
     "version": "main",
     "bitness": 64,
     "uses": ["python-3.13.3-64bit", "llvm-git-main-64bit", "node-22.16.0-64bit", "emscripten-main-64bit", "binaryen-main-64bit"],
-    "os": "win"
+    "os": "windows"
   },
   {
     "version": "main",
@@ -720,7 +720,7 @@
     "version": "releases-%releases-tag%",
     "bitness": 64,
     "uses": ["node-22.16.0-64bit", "python-3.13.3-64bit", "releases-%releases-tag%-64bit"],
-    "os": "win",
+    "os": "windows",
     "custom_install_script": "sdk_post_install"
   }
   ]