Zed remote extension fails to start streamd because no binary is installed #127

Closed
opened 2026-08-06 17:35:39 +02:00 by kfickel · 2 comments
Owner

Description:

When using the streamd Zed extension through Zed Remote Development in WSL, the language server fails to start:

failed to spawn command ...
"/home/fickelk/.local/share/zed/remote_extensions/work/streamd/streamd" "lsp":
No such file or directory (os error 2)

The extension is installed inside the WSL remote environment:

~/.local/share/zed/remote_extensions/streamd/
├── extension.toml
└── extension.wasm

However, its work directory is empty:

~/.local/share/zed/remote_extensions/work/streamd/

The extension implementation currently returns a bare streamd command on non-Windows platforms:

Ok(Command {
    command: "streamd".into(),
    args: vec!["lsp".into()],
    env: vec![],
})

In the remote-extension context, Zed resolves this to the extension work path:

~/.local/share/zed/remote_extensions/work/streamd/streamd

but no executable is downloaded, copied, or built there.

Expected behavior:

The extension should install or download an appropriate platform-specific streamd binary before returning the language server command. In a WSL remote environment, this should be a Linux executable, for example x86_64-unknown-linux-gnu.

Alternatively, the extension could support a configurable absolute executable path for users who install streamd themselves.

Suggested fix:

Implement binary installation/download logic in zed-extension/src/lib.rs, then return the resulting executable path. The release workflow should publish platform-specific artifacts that the extension can retrieve.

The current Windows-specific wsl streamd lsp branch should also be reconsidered: remote Zed already runs the extension in WSL, while local Windows Zed should not require a separate WSL installation unless that is explicitly intended.

**Description:** When using the `streamd` Zed extension through Zed Remote Development in WSL, the language server fails to start: ```text failed to spawn command ... "/home/fickelk/.local/share/zed/remote_extensions/work/streamd/streamd" "lsp": No such file or directory (os error 2) ``` The extension is installed inside the WSL remote environment: ```text ~/.local/share/zed/remote_extensions/streamd/ ├── extension.toml └── extension.wasm ``` However, its work directory is empty: ```text ~/.local/share/zed/remote_extensions/work/streamd/ ``` The extension implementation currently returns a bare `streamd` command on non-Windows platforms: ```rust Ok(Command { command: "streamd".into(), args: vec!["lsp".into()], env: vec![], }) ``` In the remote-extension context, Zed resolves this to the extension work path: ```text ~/.local/share/zed/remote_extensions/work/streamd/streamd ``` but no executable is downloaded, copied, or built there. **Expected behavior:** The extension should install or download an appropriate platform-specific `streamd` binary before returning the language server command. In a WSL remote environment, this should be a Linux executable, for example `x86_64-unknown-linux-gnu`. Alternatively, the extension could support a configurable absolute executable path for users who install `streamd` themselves. **Suggested fix:** Implement binary installation/download logic in `zed-extension/src/lib.rs`, then return the resulting executable path. The release workflow should publish platform-specific artifacts that the extension can retrieve. The current Windows-specific `wsl streamd lsp` branch should also be reconsidered: remote Zed already runs the extension in WSL, while local Windows Zed should not require a separate WSL installation unless that is explicitly intended.
Author
Owner

Implementation Plan

Context

The Zed extension's language_server_command currently just returns a bare "streamd" command (or, on Windows, shells out to wsl streamd lsp) and assumes a streamd binary is already reachable. Under Zed Remote Development (e.g. connecting to a WSL2 or SSH remote), Zed resolves that command relative to the extension's private work directory (~/.local/share/zed/remote_extensions/work/streamd/streamd), which the extension never populates — nothing downloads, copies, or builds a binary there, so the LSP fails with No such file or directory.

The fix: make the extension self-sufficient. It should auto-download the correct platform-specific prebuilt streamd binary into its own work directory and run that, while still preferring an already-installed streamd found on PATH. The WSL-specific Windows branch is removed entirely — under Remote Development the extension already executes inside the remote host directly, and local Windows Zed should run the native .exe without requiring WSL.

Confirmed scope decisions:

  • macOS: no prebuilt binary exists (no Nix cross-Darwin toolchain in this repo) and building one is out of scope here. The extension must detect Os::Mac and fail with a clear, friendly error instead of attempting a download that 404s.
  • No new configurable path setting. Only Worktree::which("streamd") is used to prefer an existing on-PATH install; this is checked before the platform-support check, so users who already have streamd on PATH (including on macOS/ARM) never hit the "unsupported platform" error.
  • No checksum/SHA256 verification. Downloads come straight from the project's own Forgejo instance over HTTPS; deferred as a possible fast-follow.

Current state (verified)

zed-extension/src/lib.rs (30 lines): returns bare "streamd" on non-Windows, wsl streamd lsp on Windows. No download/cache/install logic, no use of Worktree::which.

zed-extension/extension.toml: version = "0.0.1", hardcoded, never bumped.

zed-extension/Cargo.toml: only dependency is zed_extension_api = "0.7" (pinned to 0.7.0). Relevant APIs it exposes (confirmed from the vendored crate source):

  • current_platform() -> (Os, Architecture)Os = Mac|Linux|Windows, Architecture = Aarch64|X86|X8664.
  • download_file(url, file_path, file_type) -> Result<(), String> — file is saved relative to the extension's private working directory; file_type is Gzip|GzipTar|Zip|Uncompressed.
  • make_file_executable(filepath) -> Result<(), String>.
  • set_language_server_installation_status(id, status) where status is None|Downloading|CheckingForUpdate|Failed(String).
  • Worktree::which(binary_name) -> Option<String> — absolute path if found on PATH.
  • No Forgejo-release equivalent to latest_github_release, and no built-in checksum verification.

Release artifacts (from .forgejo/workflows/release.yml, built entirely via Nix from a single nix runner — no matrix, no macOS/ARM builder): raw (unarchived, unchecksummed) files uploaded to https://git.konstantinfickel.de/kfickel/streamd/releases/download/v<VERSION>/<artifact>:

  • streamd-<VERSION>-linux-x86_64
  • streamd-<VERSION>-windows-x86_64.exe
  • streamd-zed-extension-<VERSION>.zip (built by nix build .#zed-extension-zip, already rebuilt every release job)

flake.nix's mkZedExtension (lines 92–125) builds the wasm from src = ./zed-extension only (root Cargo.toml is not in scope for this derivation), with version = "0.0.1" hardcoded at line 105. The top-level version binding (flake.nix:34, read from root Cargo.toml) is already in lexical scope inside mkZedExtension's let block, same as it is for mkStreamdMusl/mkStreamdWindows (which already do inherit version; and set derivation-level env vars like CARGO_BUILD_TARGET). mkZedExtensionZip (lines 232–245) copies extension.toml/extension.wasm straight from mkZedExtension's output — so fixing the version at that layer propagates automatically, no separate change needed there.

Implementation

1. zed-extension/src/lib.rs

Add module-level constants:

const STREAMD_VERSION: &str = match option_env!("STREAMD_VERSION") {
    Some(v) => v,
    None => env!("CARGO_PKG_VERSION"), // local `cargo component build` fallback
};
const RELEASE_BASE_URL: &str =
    "https://git.konstantinfickel.de/kfickel/streamd/releases/download";

Add a pure helper (no host imports — trivially unit-testable later if ever wanted):

fn release_asset_name(os: Os, arch: Architecture) -> Result<String, String> {
    if os == Os::Mac {
        return Err("Precompiled streamd binaries are not available for macOS yet. \
                     Install streamd manually and make sure it is on your PATH.".into());
    }
    if arch != Architecture::X8664 {
        return Err(format!(
            "Precompiled streamd binaries are only available for x86_64. \
             Install streamd manually and make sure it is on your PATH."
        ));
    }
    Ok(match os {
        Os::Linux => format!("streamd-{STREAMD_VERSION}-linux-x86_64"),
        Os::Windows => format!("streamd-{STREAMD_VERSION}-windows-x86_64.exe"),
        Os::Mac => unreachable!(),
    })
}

Rewrite language_server_command (both params become used, drop the _ prefixes) with this control flow:

  1. if let Some(path) = worktree.which("streamd") { return Ok(Command { command: path, args: vec!["lsp".into()], env: vec![] }); }
  2. let (os, arch) = current_platform();
  3. let asset_name = release_asset_name(os, arch) — on Err(msg), call set_language_server_installation_status(language_server_id, &LanguageServerInstallationStatus::Failed(msg.clone())) and return Err(msg).
  4. If !Path::new(&asset_name).exists() (cache miss — the version is embedded in the filename, so an upgrade naturally invalidates the cache via a new filename, no explicit cache-busting needed):
    • set_language_server_installation_status(id, &Downloading)
    • download_file(&format!("{RELEASE_BASE_URL}/v{STREAMD_VERSION}/{asset_name}"), &asset_name, DownloadedFileType::Uncompressed) (raw executables, not archives) — on error, set Failed and return Err.
    • If os != Os::Windows, call make_file_executable(&asset_name) (skip on Windows — no permission bit there) — on error, set Failed and return Err.
  5. Resolve the absolute path: std::env::current_dir()?.join(&asset_name) and return it as Command { command: <absolute_path>, args: vec!["lsp".into()], env: vec![] }. Returning an absolute path (rather than relying on Zed's relative resolution) is the direct fix for the reported bug.
  6. Delete the old if os == Os::Windows { wsl ... } else { streamd ... } branch entirely.

Extend the use zed_extension_api::{...} import to include Architecture, DownloadedFileType, LanguageServerInstallationStatus, download_file, make_file_executable (all re-exported at the crate root, no new deps needed in Cargo.toml).

2. flake.nixmkZedExtension (lines 92–125)

  • version = "0.0.1";inherit version; (use the same root-Cargo.toml-derived binding every other package uses).
  • Add STREAMD_VERSION = version; as a derivation attribute (same mechanism already used for CARGO_BUILD_TARGET elsewhere in this file) — cargo component build picks it up via option_env! at compile time.
  • Add a postPatch phase to stamp the real version into extension.toml before packaging:
    postPatch = ''
      substituteInPlace extension.toml --replace-fail 'version = "0.0.1"' 'version = "${version}"'
    '';
    
    --replace-fail (not --replace) so the build breaks loudly if the placeholder string ever drifts, instead of silently shipping a stale version.

No changes needed to mkZedExtensionZip — it already copies extension.toml/extension.wasm from mkZedExtension's (now-patched) output and already names the zip from the same version binding.

3. zed-extension/extension.toml

Leave version = "0.0.1" in the source file as-is — it's now an explicit build-time placeholder, overwritten by the Nix postPatch above for every real release build. Do not hand-maintain it.

4. .forgejo/workflows/release.yml

No changes needed. It already reruns nix build .#zed-extension-zip every release, and its own VERSION (parsed from Cargo.toml for tagging) is read from the same source of truth as the Nix version binding — they can't drift.

5. README.md (lines 156–189, "Zed Extension (WSL2)")

  • Retitle away from WSL2-only framing (e.g. #### Zed Extension), since it now covers local Windows, local Linux, and Remote Development generally.
  • Rewrite the intro to explain the extension auto-downloads the matching binary for its platform (Linux x86_64 / Windows x86_64) into Zed's extension work directory, and prefers an already-on-PATH streamd if present — so step 1 ("install streamd in WSL2 via .deb") becomes optional, kept only as an aside for users who prefer a separately managed install.
  • Add a callout that macOS and non-x86_64 platforms have no prebuilt binary yet and require a manual install on PATH, with a clear in-Zed error otherwise.
  • Keep steps 2–4 (download streamd-zed-extension-<version>.zip, extract, zed: install dev extension) — this project isn't on Zed's marketplace, so manual dev-extension install is still required regardless of this fix.
  • Keep step 5 (verify via .streamd.toml + @ completions), and consider adding a note that installing the dev extension locally is sufficient for Remote Development — Zed runs the wasm inside the remote host automatically.

Verification plan (no existing test harness for the extension — manual only)

  1. Fast iteration: cd zed-extension && cargo component build --release (optionally STREAMD_VERSION=0.2.6 cargo component build --release to exercise the real download path against a real release).
  2. Full pipeline: nix build .#zed-extension -o result from repo root; confirm ./result/extension.toml's version matches root Cargo.toml (not 0.0.1).
  3. Local Zed, download path: ensure streamd is not on PATH, install as a dev extension, open a Markdown file in a .streamd.toml directory, confirm the LSP starts and check zed: open language server logs for an absolute resolved path; confirm the binary lands on disk with exec permissions (Linux).
  4. Cache behavior: restart the LSP and confirm no second download occurs.
  5. which() fast path: put a real streamd on PATH, restart the LSP, confirm it now uses the on-PATH binary instead of the downloaded copy.
  6. The actual regression — Remote Development: connect Zed to a WSL2 (or SSH) remote without streamd preinstalled, install the dev extension, confirm the LSP starts and the binary lands at ~/.local/share/zed/remote_extensions/work/streamd/streamd-<version>-linux-x86_64 with exec permissions.
  7. Native Windows, no WSL: confirm the extension downloads and runs streamd-<version>-windows-x86_64.exe directly, with no wsl invocation anywhere.
  8. Unsupported platform messaging: on macOS/ARM (or via a throwaway local hardcode if no such machine is available), confirm the friendly error surfaces through Zed's UI/LSP logs instead of a silent hang.

Critical files

  • zed-extension/src/lib.rs
  • flake.nix (mkZedExtension, lines 92–125)
  • zed-extension/extension.toml
  • README.md (lines 156–189)
  • zed-extension/Cargo.toml (no dependency changes expected, verify while implementing)
## Implementation Plan ### Context The Zed extension's `language_server_command` currently just returns a bare `"streamd"` command (or, on Windows, shells out to `wsl streamd lsp`) and assumes a `streamd` binary is already reachable. Under Zed **Remote Development** (e.g. connecting to a WSL2 or SSH remote), Zed resolves that command relative to the extension's private work directory (`~/.local/share/zed/remote_extensions/work/streamd/streamd`), which the extension never populates — nothing downloads, copies, or builds a binary there, so the LSP fails with `No such file or directory`. The fix: make the extension self-sufficient. It should auto-download the correct platform-specific prebuilt `streamd` binary into its own work directory and run that, while still preferring an already-installed `streamd` found on `PATH`. The WSL-specific Windows branch is removed entirely — under Remote Development the extension already executes inside the remote host directly, and local Windows Zed should run the native `.exe` without requiring WSL. **Confirmed scope decisions:** - **macOS**: no prebuilt binary exists (no Nix cross-Darwin toolchain in this repo) and building one is out of scope here. The extension must detect `Os::Mac` and fail with a clear, friendly error instead of attempting a download that 404s. - **No new configurable path setting.** Only `Worktree::which("streamd")` is used to prefer an existing on-PATH install; this is checked *before* the platform-support check, so users who already have `streamd` on PATH (including on macOS/ARM) never hit the "unsupported platform" error. - **No checksum/SHA256 verification.** Downloads come straight from the project's own Forgejo instance over HTTPS; deferred as a possible fast-follow. ### Current state (verified) `zed-extension/src/lib.rs` (30 lines): returns bare `"streamd"` on non-Windows, `wsl streamd lsp` on Windows. No download/cache/install logic, no use of `Worktree::which`. `zed-extension/extension.toml`: `version = "0.0.1"`, hardcoded, never bumped. `zed-extension/Cargo.toml`: only dependency is `zed_extension_api = "0.7"` (pinned to `0.7.0`). Relevant APIs it exposes (confirmed from the vendored crate source): - `current_platform() -> (Os, Architecture)` — `Os = Mac|Linux|Windows`, `Architecture = Aarch64|X86|X8664`. - `download_file(url, file_path, file_type) -> Result<(), String>` — file is saved **relative to the extension's private working directory**; `file_type` is `Gzip|GzipTar|Zip|Uncompressed`. - `make_file_executable(filepath) -> Result<(), String>`. - `set_language_server_installation_status(id, status)` where status is `None|Downloading|CheckingForUpdate|Failed(String)`. - `Worktree::which(binary_name) -> Option<String>` — absolute path if found on PATH. - No Forgejo-release equivalent to `latest_github_release`, and no built-in checksum verification. Release artifacts (from `.forgejo/workflows/release.yml`, built entirely via Nix from a single `nix` runner — no matrix, no macOS/ARM builder): raw (unarchived, unchecksummed) files uploaded to `https://git.konstantinfickel.de/kfickel/streamd/releases/download/v<VERSION>/<artifact>`: - `streamd-<VERSION>-linux-x86_64` - `streamd-<VERSION>-windows-x86_64.exe` - `streamd-zed-extension-<VERSION>.zip` (built by `nix build .#zed-extension-zip`, already rebuilt every release job) `flake.nix`'s `mkZedExtension` (lines 92–125) builds the wasm from `src = ./zed-extension` only (root `Cargo.toml` is **not** in scope for this derivation), with `version = "0.0.1"` hardcoded at line 105. The top-level `version` binding (`flake.nix:34`, read from root `Cargo.toml`) is already in lexical scope inside `mkZedExtension`'s `let` block, same as it is for `mkStreamdMusl`/`mkStreamdWindows` (which already do `inherit version;` and set derivation-level env vars like `CARGO_BUILD_TARGET`). `mkZedExtensionZip` (lines 232–245) copies `extension.toml`/`extension.wasm` straight from `mkZedExtension`'s output — so fixing the version at that layer propagates automatically, no separate change needed there. ### Implementation #### 1. `zed-extension/src/lib.rs` Add module-level constants: ```rust const STREAMD_VERSION: &str = match option_env!("STREAMD_VERSION") { Some(v) => v, None => env!("CARGO_PKG_VERSION"), // local `cargo component build` fallback }; const RELEASE_BASE_URL: &str = "https://git.konstantinfickel.de/kfickel/streamd/releases/download"; ``` Add a pure helper (no host imports — trivially unit-testable later if ever wanted): ```rust fn release_asset_name(os: Os, arch: Architecture) -> Result<String, String> { if os == Os::Mac { return Err("Precompiled streamd binaries are not available for macOS yet. \ Install streamd manually and make sure it is on your PATH.".into()); } if arch != Architecture::X8664 { return Err(format!( "Precompiled streamd binaries are only available for x86_64. \ Install streamd manually and make sure it is on your PATH." )); } Ok(match os { Os::Linux => format!("streamd-{STREAMD_VERSION}-linux-x86_64"), Os::Windows => format!("streamd-{STREAMD_VERSION}-windows-x86_64.exe"), Os::Mac => unreachable!(), }) } ``` Rewrite `language_server_command` (both params become used, drop the `_` prefixes) with this control flow: 1. `if let Some(path) = worktree.which("streamd") { return Ok(Command { command: path, args: vec!["lsp".into()], env: vec![] }); }` 2. `let (os, arch) = current_platform();` 3. `let asset_name = release_asset_name(os, arch)` — on `Err(msg)`, call `set_language_server_installation_status(language_server_id, &LanguageServerInstallationStatus::Failed(msg.clone()))` and return `Err(msg)`. 4. If `!Path::new(&asset_name).exists()` (cache miss — the version is embedded in the filename, so an upgrade naturally invalidates the cache via a new filename, no explicit cache-busting needed): - `set_language_server_installation_status(id, &Downloading)` - `download_file(&format!("{RELEASE_BASE_URL}/v{STREAMD_VERSION}/{asset_name}"), &asset_name, DownloadedFileType::Uncompressed)` (raw executables, not archives) — on error, set `Failed` and return `Err`. - If `os != Os::Windows`, call `make_file_executable(&asset_name)` (skip on Windows — no permission bit there) — on error, set `Failed` and return `Err`. 5. Resolve the absolute path: `std::env::current_dir()?.join(&asset_name)` and return it as `Command { command: <absolute_path>, args: vec!["lsp".into()], env: vec![] }`. Returning an absolute path (rather than relying on Zed's relative resolution) is the direct fix for the reported bug. 6. Delete the old `if os == Os::Windows { wsl ... } else { streamd ... }` branch entirely. Extend the `use zed_extension_api::{...}` import to include `Architecture`, `DownloadedFileType`, `LanguageServerInstallationStatus`, `download_file`, `make_file_executable` (all re-exported at the crate root, no new deps needed in `Cargo.toml`). #### 2. `flake.nix` — `mkZedExtension` (lines 92–125) - `version = "0.0.1";` → `inherit version;` (use the same root-Cargo.toml-derived binding every other package uses). - Add `STREAMD_VERSION = version;` as a derivation attribute (same mechanism already used for `CARGO_BUILD_TARGET` elsewhere in this file) — `cargo component build` picks it up via `option_env!` at compile time. - Add a `postPatch` phase to stamp the real version into `extension.toml` before packaging: ``` postPatch = '' substituteInPlace extension.toml --replace-fail 'version = "0.0.1"' 'version = "${version}"' ''; ``` `--replace-fail` (not `--replace`) so the build breaks loudly if the placeholder string ever drifts, instead of silently shipping a stale version. No changes needed to `mkZedExtensionZip` — it already copies `extension.toml`/`extension.wasm` from `mkZedExtension`'s (now-patched) output and already names the zip from the same `version` binding. #### 3. `zed-extension/extension.toml` Leave `version = "0.0.1"` in the source file as-is — it's now an explicit build-time placeholder, overwritten by the Nix `postPatch` above for every real release build. Do not hand-maintain it. #### 4. `.forgejo/workflows/release.yml` No changes needed. It already reruns `nix build .#zed-extension-zip` every release, and its own `VERSION` (parsed from `Cargo.toml` for tagging) is read from the same source of truth as the Nix `version` binding — they can't drift. #### 5. `README.md` (lines 156–189, "Zed Extension (WSL2)") - Retitle away from WSL2-only framing (e.g. `#### Zed Extension`), since it now covers local Windows, local Linux, and Remote Development generally. - Rewrite the intro to explain the extension auto-downloads the matching binary for its platform (Linux x86_64 / Windows x86_64) into Zed's extension work directory, and prefers an already-on-PATH `streamd` if present — so step 1 ("install streamd in WSL2 via `.deb`") becomes optional, kept only as an aside for users who prefer a separately managed install. - Add a callout that macOS and non-x86_64 platforms have no prebuilt binary yet and require a manual install on PATH, with a clear in-Zed error otherwise. - Keep steps 2–4 (download `streamd-zed-extension-<version>.zip`, extract, `zed: install dev extension`) — this project isn't on Zed's marketplace, so manual dev-extension install is still required regardless of this fix. - Keep step 5 (verify via `.streamd.toml` + `@` completions), and consider adding a note that installing the dev extension locally is sufficient for Remote Development — Zed runs the wasm inside the remote host automatically. ### Verification plan (no existing test harness for the extension — manual only) 1. **Fast iteration**: `cd zed-extension && cargo component build --release` (optionally `STREAMD_VERSION=0.2.6 cargo component build --release` to exercise the real download path against a real release). 2. **Full pipeline**: `nix build .#zed-extension -o result` from repo root; confirm `./result/extension.toml`'s `version` matches root `Cargo.toml` (not `0.0.1`). 3. **Local Zed, download path**: ensure `streamd` is not on PATH, install as a dev extension, open a Markdown file in a `.streamd.toml` directory, confirm the LSP starts and check `zed: open language server logs` for an absolute resolved path; confirm the binary lands on disk with exec permissions (Linux). 4. **Cache behavior**: restart the LSP and confirm no second download occurs. 5. **`which()` fast path**: put a real `streamd` on PATH, restart the LSP, confirm it now uses the on-PATH binary instead of the downloaded copy. 6. **The actual regression — Remote Development**: connect Zed to a WSL2 (or SSH) remote without `streamd` preinstalled, install the dev extension, confirm the LSP starts and the binary lands at `~/.local/share/zed/remote_extensions/work/streamd/streamd-<version>-linux-x86_64` with exec permissions. 7. **Native Windows, no WSL**: confirm the extension downloads and runs `streamd-<version>-windows-x86_64.exe` directly, with no `wsl` invocation anywhere. 8. **Unsupported platform messaging**: on macOS/ARM (or via a throwaway local hardcode if no such machine is available), confirm the friendly error surfaces through Zed's UI/LSP logs instead of a silent hang. ### Critical files - `zed-extension/src/lib.rs` - `flake.nix` (`mkZedExtension`, lines 92–125) - `zed-extension/extension.toml` - `README.md` (lines 156–189) - `zed-extension/Cargo.toml` (no dependency changes expected, verify while implementing)
Author
Owner

Implementation complete — PR #128

Time: ~6 minutes from branch creation to PR open (implementation phase only; refinement/planning happened separately beforehand). Precise end-to-end token usage isn't something my tooling reports to me directly — the two research sub-agents used during refinement consumed ~63k tokens combined; I don't have a comparable figure for the implementation phase itself.

Summary of findings during implementation:

  • Followed London-style TDD for the one pure, testable unit: wrote 5 failing tests for a new release_asset_name(os, arch) helper (Linux/Windows/macOS/unsupported-arch cases) before implementing it, then implemented release_asset_name and rewrote language_server_command to make them pass.
  • Empirically confirmed cargo test compiles and links fine natively for this crate despite crate-type = ["cdylib"] and its use of wit-bindgen-generated host imports (current_platform, download_file, etc.) — no #[cfg(target_arch = "wasm32")] gating was needed, since unused extern host-import declarations don't produce link errors when never called from the test path.
  • Verified with strings on the actual compiled extension.wasm that STREAMD_VERSION (baked in via option_env! + the new Nix STREAMD_VERSION env var) and both platform-specific asset-name format strings are present in the binary, confirming the version-injection plumbing through flake.nix actually works end-to-end, not just in theory.
  • nix build .#zed-extension confirmed extension.toml's version is correctly patched from the placeholder 0.0.1 to the real 0.2.6 (matching root Cargo.toml).
  • nix build .#zed-extension-zip required no changes and picked up the patched extension.toml automatically, as anticipated in the plan.
  • nix flake check (clippy, fmt, test, pre-commit) passes cleanly with no changes needed to .forgejo/workflows/release.yml.
  • Not verified in this environment (no Zed instance available): the actual manual/Remote Development end-to-end scenarios from the original bug report (installing as a dev extension, confirming the binary lands and runs inside a real WSL2/SSH remote). Flagged as open checklist items on the PR.
## Implementation complete — PR #128 **Time:** ~6 minutes from branch creation to PR open (implementation phase only; refinement/planning happened separately beforehand). Precise end-to-end token usage isn't something my tooling reports to me directly — the two research sub-agents used during refinement consumed ~63k tokens combined; I don't have a comparable figure for the implementation phase itself. **Summary of findings during implementation:** - Followed London-style TDD for the one pure, testable unit: wrote 5 failing tests for a new `release_asset_name(os, arch)` helper (Linux/Windows/macOS/unsupported-arch cases) before implementing it, then implemented `release_asset_name` and rewrote `language_server_command` to make them pass. - Empirically confirmed `cargo test` compiles and links fine natively for this crate despite `crate-type = ["cdylib"]` and its use of `wit-bindgen`-generated host imports (`current_platform`, `download_file`, etc.) — no `#[cfg(target_arch = "wasm32")]` gating was needed, since unused `extern` host-import declarations don't produce link errors when never called from the test path. - Verified with `strings` on the actual compiled `extension.wasm` that `STREAMD_VERSION` (baked in via `option_env!` + the new Nix `STREAMD_VERSION` env var) and both platform-specific asset-name format strings are present in the binary, confirming the version-injection plumbing through `flake.nix` actually works end-to-end, not just in theory. - `nix build .#zed-extension` confirmed `extension.toml`'s `version` is correctly patched from the placeholder `0.0.1` to the real `0.2.6` (matching root `Cargo.toml`). - `nix build .#zed-extension-zip` required no changes and picked up the patched `extension.toml` automatically, as anticipated in the plan. - `nix flake check` (clippy, fmt, test, pre-commit) passes cleanly with no changes needed to `.forgejo/workflows/release.yml`. - Not verified in this environment (no Zed instance available): the actual manual/Remote Development end-to-end scenarios from the original bug report (installing as a dev extension, confirming the binary lands and runs inside a real WSL2/SSH remote). Flagged as open checklist items on the PR.
Sign in to join this conversation.
No labels
planned
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
kfickel/streamd#127
No description provided.