Remove duplicated code for unchanged parts of different extension API versions (#10218)

Max Brunsfeld , Marshall , and Marshall Bowers created

Release Notes:

- N/A

---------

Co-authored-by: Marshall <marshall@zed.dev>
Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>

Change summary

crates/extension/src/wasm_host/wit/since_v0_0_1.rs  |  67 -----
crates/extension/src/wasm_host/wit/since_v0_0_4.rs  |  67 -----
crates/extension/src/wasm_host/wit/since_v0_0_6.rs  | 152 ++++++++------
crates/extension_api/src/extension_api.rs           |  14 
crates/extension_api/src/settings.rs                |   2 
crates/extension_api/wit/since_v0.0.1/extension.wit |  30 --
crates/extension_api/wit/since_v0.0.1/github.wit    |  28 ++
crates/extension_api/wit/since_v0.0.1/platform.wit  |  24 ++
crates/extension_api/wit/since_v0.0.4/extension.wit |  30 --
crates/extension_api/wit/since_v0.0.4/github.wit    |  28 ++
crates/extension_api/wit/since_v0.0.4/platform.wit  |  24 ++
crates/extension_api/wit/since_v0.0.6/extension.wit |  66 ------
crates/extension_api/wit/since_v0.0.6/github.wit    |  28 ++
crates/extension_api/wit/since_v0.0.6/nodejs.wit    |  13 +
crates/extension_api/wit/since_v0.0.6/platform.wit  |  24 ++
15 files changed, 287 insertions(+), 310 deletions(-)

Detailed changes

crates/extension/src/wasm_host/wit/since_v0_0_1.rs 🔗

@@ -15,6 +15,8 @@ wasmtime::component::bindgen!({
     path: "../extension_api/wit/since_v0.0.1",
     with: {
          "worktree": ExtensionWorktree,
+         "zed:extension/github": latest::zed::extension::github,
+         "zed:extension/platform": latest::zed::extension::platform,
     },
 });
 
@@ -25,53 +27,6 @@ pub fn linker() -> &'static Linker<WasmState> {
     LINKER.get_or_init(|| super::new_linker(Extension::add_to_linker))
 }
 
-impl From<latest::Os> for Os {
-    fn from(value: latest::Os) -> Self {
-        match value {
-            latest::Os::Mac => Os::Mac,
-            latest::Os::Linux => Os::Linux,
-            latest::Os::Windows => Os::Windows,
-        }
-    }
-}
-
-impl From<latest::Architecture> for Architecture {
-    fn from(value: latest::Architecture) -> Self {
-        match value {
-            latest::Architecture::Aarch64 => Self::Aarch64,
-            latest::Architecture::X86 => Self::X86,
-            latest::Architecture::X8664 => Self::X8664,
-        }
-    }
-}
-
-impl From<latest::GithubRelease> for GithubRelease {
-    fn from(value: latest::GithubRelease) -> Self {
-        Self {
-            version: value.version,
-            assets: value.assets.into_iter().map(|asset| asset.into()).collect(),
-        }
-    }
-}
-
-impl From<latest::GithubReleaseAsset> for GithubReleaseAsset {
-    fn from(value: latest::GithubReleaseAsset) -> Self {
-        Self {
-            name: value.name,
-            download_url: value.download_url,
-        }
-    }
-}
-
-impl From<GithubReleaseOptions> for latest::GithubReleaseOptions {
-    fn from(value: GithubReleaseOptions) -> Self {
-        Self {
-            require_assets: value.require_assets,
-            pre_release: value.pre_release,
-        }
-    }
-}
-
 impl From<DownloadedFileType> for latest::DownloadedFileType {
     fn from(value: DownloadedFileType) -> Self {
         match value {
@@ -135,21 +90,21 @@ impl HostWorktree for WasmState {
 #[async_trait]
 impl ExtensionImports for WasmState {
     async fn node_binary_path(&mut self) -> wasmtime::Result<Result<String, String>> {
-        latest::ExtensionImports::node_binary_path(self).await
+        latest::nodejs::Host::node_binary_path(self).await
     }
 
     async fn npm_package_latest_version(
         &mut self,
         package_name: String,
     ) -> wasmtime::Result<Result<String, String>> {
-        latest::ExtensionImports::npm_package_latest_version(self, package_name).await
+        latest::nodejs::Host::npm_package_latest_version(self, package_name).await
     }
 
     async fn npm_package_installed_version(
         &mut self,
         package_name: String,
     ) -> wasmtime::Result<Result<Option<String>, String>> {
-        latest::ExtensionImports::npm_package_installed_version(self, package_name).await
+        latest::nodejs::Host::npm_package_installed_version(self, package_name).await
     }
 
     async fn npm_install_package(
@@ -157,7 +112,7 @@ impl ExtensionImports for WasmState {
         package_name: String,
         version: String,
     ) -> wasmtime::Result<Result<(), String>> {
-        latest::ExtensionImports::npm_install_package(self, package_name, version).await
+        latest::nodejs::Host::npm_install_package(self, package_name, version).await
     }
 
     async fn latest_github_release(
@@ -165,17 +120,11 @@ impl ExtensionImports for WasmState {
         repo: String,
         options: GithubReleaseOptions,
     ) -> wasmtime::Result<Result<GithubRelease, String>> {
-        Ok(
-            latest::ExtensionImports::latest_github_release(self, repo, options.into())
-                .await?
-                .map(|github| github.into()),
-        )
+        latest::zed::extension::github::Host::latest_github_release(self, repo, options).await
     }
 
     async fn current_platform(&mut self) -> Result<(Os, Architecture)> {
-        latest::ExtensionImports::current_platform(self)
-            .await
-            .map(|(os, arch)| (os.into(), arch.into()))
+        latest::zed::extension::platform::Host::current_platform(self).await
     }
 
     async fn set_language_server_installation_status(

crates/extension/src/wasm_host/wit/since_v0_0_4.rs 🔗

@@ -14,6 +14,8 @@ wasmtime::component::bindgen!({
     path: "../extension_api/wit/since_v0.0.4",
     with: {
          "worktree": ExtensionWorktree,
+         "zed:extension/github": latest::zed::extension::github,
+         "zed:extension/platform": latest::zed::extension::platform,
     },
 });
 
@@ -24,53 +26,6 @@ pub fn linker() -> &'static Linker<WasmState> {
     LINKER.get_or_init(|| super::new_linker(Extension::add_to_linker))
 }
 
-impl From<latest::Os> for Os {
-    fn from(value: latest::Os) -> Self {
-        match value {
-            latest::Os::Mac => Os::Mac,
-            latest::Os::Linux => Os::Linux,
-            latest::Os::Windows => Os::Windows,
-        }
-    }
-}
-
-impl From<latest::Architecture> for Architecture {
-    fn from(value: latest::Architecture) -> Self {
-        match value {
-            latest::Architecture::Aarch64 => Self::Aarch64,
-            latest::Architecture::X86 => Self::X86,
-            latest::Architecture::X8664 => Self::X8664,
-        }
-    }
-}
-
-impl From<latest::GithubRelease> for GithubRelease {
-    fn from(value: latest::GithubRelease) -> Self {
-        Self {
-            version: value.version,
-            assets: value.assets.into_iter().map(|asset| asset.into()).collect(),
-        }
-    }
-}
-
-impl From<latest::GithubReleaseAsset> for GithubReleaseAsset {
-    fn from(value: latest::GithubReleaseAsset) -> Self {
-        Self {
-            name: value.name,
-            download_url: value.download_url,
-        }
-    }
-}
-
-impl From<GithubReleaseOptions> for latest::GithubReleaseOptions {
-    fn from(value: GithubReleaseOptions) -> Self {
-        Self {
-            require_assets: value.require_assets,
-            pre_release: value.pre_release,
-        }
-    }
-}
-
 impl From<DownloadedFileType> for latest::DownloadedFileType {
     fn from(value: DownloadedFileType) -> Self {
         match value {
@@ -145,21 +100,21 @@ impl HostWorktree for WasmState {
 #[async_trait]
 impl ExtensionImports for WasmState {
     async fn node_binary_path(&mut self) -> wasmtime::Result<Result<String, String>> {
-        latest::ExtensionImports::node_binary_path(self).await
+        latest::nodejs::Host::node_binary_path(self).await
     }
 
     async fn npm_package_latest_version(
         &mut self,
         package_name: String,
     ) -> wasmtime::Result<Result<String, String>> {
-        latest::ExtensionImports::npm_package_latest_version(self, package_name).await
+        latest::nodejs::Host::npm_package_latest_version(self, package_name).await
     }
 
     async fn npm_package_installed_version(
         &mut self,
         package_name: String,
     ) -> wasmtime::Result<Result<Option<String>, String>> {
-        latest::ExtensionImports::npm_package_installed_version(self, package_name).await
+        latest::nodejs::Host::npm_package_installed_version(self, package_name).await
     }
 
     async fn npm_install_package(
@@ -167,7 +122,7 @@ impl ExtensionImports for WasmState {
         package_name: String,
         version: String,
     ) -> wasmtime::Result<Result<(), String>> {
-        latest::ExtensionImports::npm_install_package(self, package_name, version).await
+        latest::nodejs::Host::npm_install_package(self, package_name, version).await
     }
 
     async fn latest_github_release(
@@ -175,17 +130,11 @@ impl ExtensionImports for WasmState {
         repo: String,
         options: GithubReleaseOptions,
     ) -> wasmtime::Result<Result<GithubRelease, String>> {
-        Ok(
-            latest::ExtensionImports::latest_github_release(self, repo, options.into())
-                .await?
-                .map(|github| github.into()),
-        )
+        latest::zed::extension::github::Host::latest_github_release(self, repo, options).await
     }
 
     async fn current_platform(&mut self) -> Result<(Os, Architecture)> {
-        latest::ExtensionImports::current_platform(self)
-            .await
-            .map(|(os, arch)| (os.into(), arch.into()))
+        latest::zed::extension::platform::Host::current_platform(self).await
     }
 
     async fn set_language_server_installation_status(

crates/extension/src/wasm_host/wit/since_v0_0_6.rs 🔗

@@ -1,13 +1,13 @@
-use crate::wasm_host::wit::ToWasmtimeResult;
-use crate::wasm_host::WasmState;
+use crate::wasm_host::{wit::ToWasmtimeResult, WasmState};
 use ::settings::Settings;
 use anyhow::{anyhow, bail, Result};
 use async_compression::futures::bufread::GzipDecoder;
 use async_tar::Archive;
 use async_trait::async_trait;
 use futures::{io::BufReader, FutureExt as _};
-use language::language_settings::AllLanguageSettings;
-use language::{LanguageServerBinaryStatus, LspAdapterDelegate};
+use language::{
+    language_settings::AllLanguageSettings, LanguageServerBinaryStatus, LspAdapterDelegate,
+};
 use project::project_settings::ProjectSettings;
 use semantic_version::SemanticVersion;
 use std::{
@@ -29,6 +29,8 @@ wasmtime::component::bindgen!({
     },
 });
 
+pub use self::zed::extension::*;
+
 mod settings {
     include!("../../../../extension_api/wit/since_v0.0.6/settings.rs");
 }
@@ -96,62 +98,8 @@ impl HostWorktree for WasmState {
     }
 }
 
-impl self::zed::extension::lsp::Host for WasmState {}
-
 #[async_trait]
-impl ExtensionImports for WasmState {
-    async fn get_settings(
-        &mut self,
-        location: Option<self::SettingsLocation>,
-        category: String,
-        key: Option<String>,
-    ) -> wasmtime::Result<Result<String, String>> {
-        self.on_main_thread(|cx| {
-            async move {
-                let location = location
-                    .as_ref()
-                    .map(|location| ::settings::SettingsLocation {
-                        worktree_id: location.worktree_id as usize,
-                        path: Path::new(&location.path),
-                    });
-
-                cx.update(|cx| match category.as_str() {
-                    "language" => {
-                        let settings =
-                            AllLanguageSettings::get(location, cx).language(key.as_deref());
-                        Ok(serde_json::to_string(&settings::LanguageSettings {
-                            tab_size: settings.tab_size,
-                        })?)
-                    }
-                    "lsp" => {
-                        let settings = key
-                            .and_then(|key| {
-                                ProjectSettings::get_global(cx)
-                                    .lsp
-                                    .get(&Arc::<str>::from(key))
-                            })
-                            .cloned()
-                            .unwrap_or_default();
-                        Ok(serde_json::to_string(&settings::LspSettings {
-                            binary: settings.binary.map(|binary| settings::BinarySettings {
-                                path: binary.path,
-                                arguments: binary.arguments,
-                            }),
-                            settings: settings.settings,
-                            initialization_options: settings.initialization_options,
-                        })?)
-                    }
-                    _ => {
-                        bail!("Unknown settings category: {}", category);
-                    }
-                })
-            }
-            .boxed_local()
-        })
-        .await?
-        .to_wasmtime_result()
-    }
-
+impl nodejs::Host for WasmState {
     async fn node_binary_path(&mut self) -> wasmtime::Result<Result<String, String>> {
         self.host
             .node_runtime
@@ -194,12 +142,18 @@ impl ExtensionImports for WasmState {
             .await
             .to_wasmtime_result()
     }
+}
+
+#[async_trait]
+impl lsp::Host for WasmState {}
 
+#[async_trait]
+impl github::Host for WasmState {
     async fn latest_github_release(
         &mut self,
         repo: String,
-        options: GithubReleaseOptions,
-    ) -> wasmtime::Result<Result<GithubRelease, String>> {
+        options: github::GithubReleaseOptions,
+    ) -> wasmtime::Result<Result<github::GithubRelease, String>> {
         maybe!(async {
             let release = util::github::latest_github_release(
                 &repo,
@@ -208,12 +162,12 @@ impl ExtensionImports for WasmState {
                 self.host.http_client.clone(),
             )
             .await?;
-            Ok(GithubRelease {
+            Ok(github::GithubRelease {
                 version: release.tag_name,
                 assets: release
                     .assets
                     .into_iter()
-                    .map(|asset| GithubReleaseAsset {
+                    .map(|asset| github::GithubReleaseAsset {
                         name: asset.name,
                         download_url: asset.browser_download_url,
                     })
@@ -223,23 +177,81 @@ impl ExtensionImports for WasmState {
         .await
         .to_wasmtime_result()
     }
+}
 
-    async fn current_platform(&mut self) -> Result<(Os, Architecture)> {
+#[async_trait]
+impl platform::Host for WasmState {
+    async fn current_platform(&mut self) -> Result<(platform::Os, platform::Architecture)> {
         Ok((
             match env::consts::OS {
-                "macos" => Os::Mac,
-                "linux" => Os::Linux,
-                "windows" => Os::Windows,
+                "macos" => platform::Os::Mac,
+                "linux" => platform::Os::Linux,
+                "windows" => platform::Os::Windows,
                 _ => panic!("unsupported os"),
             },
             match env::consts::ARCH {
-                "aarch64" => Architecture::Aarch64,
-                "x86" => Architecture::X86,
-                "x86_64" => Architecture::X8664,
+                "aarch64" => platform::Architecture::Aarch64,
+                "x86" => platform::Architecture::X86,
+                "x86_64" => platform::Architecture::X8664,
                 _ => panic!("unsupported architecture"),
             },
         ))
     }
+}
+
+#[async_trait]
+impl ExtensionImports for WasmState {
+    async fn get_settings(
+        &mut self,
+        location: Option<self::SettingsLocation>,
+        category: String,
+        key: Option<String>,
+    ) -> wasmtime::Result<Result<String, String>> {
+        self.on_main_thread(|cx| {
+            async move {
+                let location = location
+                    .as_ref()
+                    .map(|location| ::settings::SettingsLocation {
+                        worktree_id: location.worktree_id as usize,
+                        path: Path::new(&location.path),
+                    });
+
+                cx.update(|cx| match category.as_str() {
+                    "language" => {
+                        let settings =
+                            AllLanguageSettings::get(location, cx).language(key.as_deref());
+                        Ok(serde_json::to_string(&settings::LanguageSettings {
+                            tab_size: settings.tab_size,
+                        })?)
+                    }
+                    "lsp" => {
+                        let settings = key
+                            .and_then(|key| {
+                                ProjectSettings::get_global(cx)
+                                    .lsp
+                                    .get(&Arc::<str>::from(key))
+                            })
+                            .cloned()
+                            .unwrap_or_default();
+                        Ok(serde_json::to_string(&settings::LspSettings {
+                            binary: settings.binary.map(|binary| settings::BinarySettings {
+                                path: binary.path,
+                                arguments: binary.arguments,
+                            }),
+                            settings: settings.settings,
+                            initialization_options: settings.initialization_options,
+                        })?)
+                    }
+                    _ => {
+                        bail!("Unknown settings category: {}", category);
+                    }
+                })
+            }
+            .boxed_local()
+        })
+        .await?
+        .to_wasmtime_result()
+    }
 
     async fn set_language_server_installation_status(
         &mut self,

crates/extension_api/src/extension_api.rs 🔗

@@ -13,11 +13,17 @@ pub use serde_json;
 // We explicitly enumerate the symbols we want to re-export, as there are some
 // that we may want to shadow to provide a cleaner Rust API.
 pub use wit::{
-    current_platform, download_file, latest_github_release, make_file_executable, node_binary_path,
-    npm_install_package, npm_package_installed_version, npm_package_latest_version, Architecture,
+    download_file, make_file_executable,
+    zed::extension::github::{
+        latest_github_release, GithubRelease, GithubReleaseAsset, GithubReleaseOptions,
+    },
+    zed::extension::nodejs::{
+        node_binary_path, npm_install_package, npm_package_installed_version,
+        npm_package_latest_version,
+    },
+    zed::extension::platform::{current_platform, Architecture, Os},
     CodeLabel, CodeLabelSpan, CodeLabelSpanLiteral, Command, DownloadedFileType, EnvVars,
-    GithubRelease, GithubReleaseAsset, GithubReleaseOptions, LanguageServerInstallationStatus, Os,
-    Range, Worktree,
+    LanguageServerInstallationStatus, Range, Worktree,
 };
 
 // Undocumented WIT re-exports.

crates/extension_api/src/settings.rs 🔗

@@ -1,5 +1,5 @@
 #[path = "../wit/since_v0.0.6/settings.rs"]
-pub mod types;
+mod types;
 
 use crate::{wit, Result, SettingsLocation, Worktree};
 use serde_json;

crates/extension_api/wit/since_v0.0.1/extension.wit 🔗

@@ -1,34 +1,10 @@
 package zed:extension;
 
 world extension {
-    export init-extension: func();
-
-    record github-release {
-        version: string,
-        assets: list<github-release-asset>,
-    }
-
-    record github-release-asset {
-        name: string,
-        download-url: string,
-    }
+    use github.{github-release, github-release-options};
+    use platform.{os, architecture};
 
-    record github-release-options {
-        require-assets: bool,
-        pre-release: bool,
-    }
-
-    enum os {
-        mac,
-        linux,
-        windows,
-    }
-
-    enum architecture {
-        aarch64,
-        x86,
-        x8664,
-    }
+    export init-extension: func();
 
     enum downloaded-file-type {
         gzip,

crates/extension_api/wit/since_v0.0.1/github.wit 🔗

@@ -0,0 +1,28 @@
+interface github {
+    /// A GitHub release.
+    record github-release {
+        /// The version of the release.
+        version: string,
+        /// The list of assets attached to the release.
+        assets: list<github-release-asset>,
+    }
+
+    /// An asset from a GitHub release.
+    record github-release-asset {
+        /// The name of the asset.
+        name: string,
+        /// The download URL for the asset.
+        download-url: string,
+    }
+
+    /// The options used to filter down GitHub releases.
+    record github-release-options {
+        /// Whether releases without assets should be included.
+        require-assets: bool,
+        /// Whether pre-releases should be included.
+        pre-release: bool,
+    }
+
+    /// Returns the latest release for the given GitHub repository.
+    latest-github-release: func(repo: string, options: github-release-options) -> result<github-release, string>;
+}

crates/extension_api/wit/since_v0.0.1/platform.wit 🔗

@@ -0,0 +1,24 @@
+interface platform {
+    /// An operating system.
+    enum os {
+        /// macOS.
+        mac,
+        /// Linux.
+        linux,
+        /// Windows.
+        windows,
+    }
+
+    /// A platform architecture.
+    enum architecture {
+        /// AArch64 (e.g., Apple Silicon).
+        aarch64,
+        /// x86.
+        x86,
+        /// x86-64.
+        x8664,
+    }
+
+    /// Gets the current operating system and architecture.
+    current-platform: func() -> tuple<os, architecture>;
+}

crates/extension_api/wit/since_v0.0.4/extension.wit 🔗

@@ -1,34 +1,10 @@
 package zed:extension;
 
 world extension {
-    export init-extension: func();
-
-    record github-release {
-        version: string,
-        assets: list<github-release-asset>,
-    }
-
-    record github-release-asset {
-        name: string,
-        download-url: string,
-    }
+    use github.{github-release, github-release-options};
+    use platform.{os, architecture};
 
-    record github-release-options {
-        require-assets: bool,
-        pre-release: bool,
-    }
-
-    enum os {
-        mac,
-        linux,
-        windows,
-    }
-
-    enum architecture {
-        aarch64,
-        x86,
-        x8664,
-    }
+    export init-extension: func();
 
     enum downloaded-file-type {
         gzip,

crates/extension_api/wit/since_v0.0.4/github.wit 🔗

@@ -0,0 +1,28 @@
+interface github {
+    /// A GitHub release.
+    record github-release {
+        /// The version of the release.
+        version: string,
+        /// The list of assets attached to the release.
+        assets: list<github-release-asset>,
+    }
+
+    /// An asset from a GitHub release.
+    record github-release-asset {
+        /// The name of the asset.
+        name: string,
+        /// The download URL for the asset.
+        download-url: string,
+    }
+
+    /// The options used to filter down GitHub releases.
+    record github-release-options {
+        /// Whether releases without assets should be included.
+        require-assets: bool,
+        /// Whether pre-releases should be included.
+        pre-release: bool,
+    }
+
+    /// Returns the latest release for the given GitHub repository.
+    latest-github-release: func(repo: string, options: github-release-options) -> result<github-release, string>;
+}

crates/extension_api/wit/since_v0.0.4/platform.wit 🔗

@@ -0,0 +1,24 @@
+interface platform {
+    /// An operating system.
+    enum os {
+        /// macOS.
+        mac,
+        /// Linux.
+        linux,
+        /// Windows.
+        windows,
+    }
+
+    /// A platform architecture.
+    enum architecture {
+        /// AArch64 (e.g., Apple Silicon).
+        aarch64,
+        /// x86.
+        x86,
+        /// x86-64.
+        x8664,
+    }
+
+    /// Gets the current operating system and architecture.
+    current-platform: func() -> tuple<os, architecture>;
+}

crates/extension_api/wit/since_v0.0.6/extension.wit 🔗

@@ -1,57 +1,15 @@
 package zed:extension;
 
 world extension {
-    import lsp;
+    import github;
+    import platform;
+    import nodejs;
 
     use lsp.{completion, symbol};
 
     /// Initializes the extension.
     export init-extension: func();
 
-    /// A GitHub release.
-    record github-release {
-        /// The version of the release.
-        version: string,
-        /// The list of assets attached to the release.
-        assets: list<github-release-asset>,
-    }
-
-    /// An asset from a GitHub release.
-    record github-release-asset {
-        /// The name of the asset.
-        name: string,
-        /// The download URL for the asset.
-        download-url: string,
-    }
-
-    /// The options used to filter down GitHub releases.
-    record github-release-options {
-        /// Whether releases without assets should be included.
-        require-assets: bool,
-        /// Whether pre-releases should be included.
-        pre-release: bool,
-    }
-
-    /// An operating system.
-    enum os {
-        /// macOS.
-        mac,
-        /// Linux.
-        linux,
-        /// Windows.
-        windows,
-    }
-
-    /// A platform architecture.
-    enum architecture {
-        /// AArch64 (e.g., Apple Silicon).
-        aarch64,
-        /// x86.
-        x86,
-        /// x86-64.
-        x8664,
-    }
-
     /// The type of a downloaded file.
     enum downloaded-file-type {
         /// A gzipped file (`.gz`).
@@ -76,9 +34,6 @@ world extension {
         failed(string),
     }
 
-    /// Returns operating system and architecture for the current platform.
-    import current-platform: func() -> tuple<os, architecture>;
-
     record settings-location {
         worktree-id: u64,
         path: string,
@@ -86,21 +41,6 @@ world extension {
 
     import get-settings: func(path: option<settings-location>, category: string, key: option<string>) -> result<string, string>;
 
-    /// Returns the path to the Node binary used by Zed.
-    import node-binary-path: func() -> result<string, string>;
-
-    /// Returns the latest version of the given NPM package.
-    import npm-package-latest-version: func(package-name: string) -> result<string, string>;
-
-    /// Returns the installed version of the given NPM package, if it exists.
-    import npm-package-installed-version: func(package-name: string) -> result<option<string>, string>;
-
-    /// Installs the specified NPM package.
-    import npm-install-package: func(package-name: string, version: string) -> result<_, string>;
-
-    /// Returns the latest release for the given GitHub repository.
-    import latest-github-release: func(repo: string, options: github-release-options) -> result<github-release, string>;
-
     /// Downloads a file from the given URL and saves it to the given path within the extension's
     /// working directory.
     ///

crates/extension_api/wit/since_v0.0.6/github.wit 🔗

@@ -0,0 +1,28 @@
+interface github {
+    /// A GitHub release.
+    record github-release {
+        /// The version of the release.
+        version: string,
+        /// The list of assets attached to the release.
+        assets: list<github-release-asset>,
+    }
+
+    /// An asset from a GitHub release.
+    record github-release-asset {
+        /// The name of the asset.
+        name: string,
+        /// The download URL for the asset.
+        download-url: string,
+    }
+
+    /// The options used to filter down GitHub releases.
+    record github-release-options {
+        /// Whether releases without assets should be included.
+        require-assets: bool,
+        /// Whether pre-releases should be included.
+        pre-release: bool,
+    }
+
+    /// Returns the latest release for the given GitHub repository.
+    latest-github-release: func(repo: string, options: github-release-options) -> result<github-release, string>;
+}

crates/extension_api/wit/since_v0.0.6/nodejs.wit 🔗

@@ -0,0 +1,13 @@
+interface nodejs {
+    /// Returns the path to the Node binary used by Zed.
+    node-binary-path: func() -> result<string, string>;
+
+    /// Returns the latest version of the given NPM package.
+    npm-package-latest-version: func(package-name: string) -> result<string, string>;
+
+    /// Returns the installed version of the given NPM package, if it exists.
+    npm-package-installed-version: func(package-name: string) -> result<option<string>, string>;
+
+    /// Installs the specified NPM package.
+    npm-install-package: func(package-name: string, version: string) -> result<_, string>;
+}

crates/extension_api/wit/since_v0.0.6/platform.wit 🔗

@@ -0,0 +1,24 @@
+interface platform {
+    /// An operating system.
+    enum os {
+        /// macOS.
+        mac,
+        /// Linux.
+        linux,
+        /// Windows.
+        windows,
+    }
+
+    /// A platform architecture.
+    enum architecture {
+        /// AArch64 (e.g., Apple Silicon).
+        aarch64,
+        /// x86.
+        x86,
+        /// x86-64.
+        x8664,
+    }
+
+    /// Gets the current operating system and architecture.
+    current-platform: func() -> tuple<os, architecture>;
+}