Conversation
| # Zed selects an absolute Node path at runtime. The resolver reads project | ||
| # manifests and executable metadata through Node because WASI cannot read them. | ||
| [[capabilities]] | ||
| kind = "process:exec" | ||
| command = "*" | ||
| args = ["-e", "*", "--", "ancestors", "*", "*"] | ||
|
|
||
| [[capabilities]] | ||
| kind = "process:exec" | ||
| command = "*" | ||
| args = ["-e", "*", "--", "executable", "*", "*"] | ||
|
|
||
| [[capabilities]] | ||
| kind = "process:exec" | ||
| command = "*" | ||
| args = ["-e", "*", "--", "global", "*", "vp"] |
There was a problem hiding this comment.
do we know if Zed will reject the extension for doing this wildcard? Is there any better option here?
There was a problem hiding this comment.
There is a close accepted precedent. Haxe uses command = "*" to run an embedded discovery script through node_binary_path(). Its maintainer initially requested changes, then approved an exception. That decision does not guarantee acceptance of our helper. Implementation, review.
The wildcard handles the absolute Node path that Zed selects at runtime. Zed matches complete command strings or "*", so command = "node" does not match that path. Calling node through PATH would still leave the filesystem workaround. Matcher.
Our script reads ancestor manifests, installed package entries, and executable metadata. These reads extend beyond Haxe's directory scan. Our argument patterns are more specific, but the wildcard script argument does not enforce filesystem limits.
Using only the Worktree API would lose ancestor discovery and executable inspection. I propose documenting the helper in extension.toml and requesting an exception from Zed maintainers for this access scope.
There was a problem hiding this comment.
I’ll try reducing the permissions to see how it affects the functionality.
There was a problem hiding this comment.
@connorshea Since src/binary_resolver/inspect.js can be reviewed, I suggest keeping this permission request for now and adjusting it based on the feedback during the plugin submission process. If it is indeed not allowed, we can switch to an approach that does not require the permission.
|
For further assessment, here is the expected impact of removing the new This requires a resolver refactor. Removing the declarations alone would make the current inspection calls fail.
For example, opening The launcher cleanup logic is separate from filesystem inspection. Removing these permissions does not require removing that cleanup logic. Zed exposes worktree reads and executable lookup through its standard API. The capability documentation distinguishes helper execution from npm installation. This gives us a possible fallback if Zed declines the current filesystem helper. It retains core LSP functionality and conventional local installations, with manual configuration for more complex layouts. This is a design assessment; the alternative is not implemented. |
The current integration starts the legacy
vite-plus/bin/oxlintandvite-plus/bin/oxfmtwrappers. These paths fail when an installation no longer includes the wrappers. The extension now startsvp lint --lsporvp fmt --lspfrom the selected package directory.By default, detection checks the opened worktree and its ancestors through the first monorepo root. A direct
vite-plusdependency takes priority over standaloneoxlintoroxfmt. The resolver checks local installations beforePATH. If the selectedvpexecutable is missing, startup stops with an installation hint. Standalone selection supports local and hoisted installations, with the extension's managed installation as a fallback.Users can set
binarySourcetoauto,vite-plus, oroxcunderlsp.<tool>.initialization_options.settings. An optionalvpPathin the same object selects a specificvpexecutable. For source selection,lsp.<tool>.settingsoverrides matching values.binary.pathoverrides keep priority, with optionalbinary.arguments. Source changes require a language server restart.Oxlint startup comparison
This diagram shows default source selection, without
binary.pathorvpPathoverrides. Oxfmt follows the same selection process and usesvp fmt --lsp.flowchart LR subgraph Before["Before"] direction TB B0["Read the opened worktree's package.json"] --> B1["Choose a declared package:<br/>oxlint before vite-plus"] B1 --> B2{"Dependency found?"} B2 -->|Yes| B3["Select its bin/oxlint script"] B2 -->|No| B4["Install or update<br/>extension-managed Oxlint"] B3 --> B5["node selected-script --lsp"] B4 --> B5 end subgraph After["After"] direction TB A0["Inspect the worktree and ancestors<br/>through the monorepo root"] --> A1{"Declares vite-plus?"} A1 -->|Yes| A2["Resolve local vp,<br/>otherwise search PATH"] A2 --> A3{"vp found?"} A3 -->|Yes| A4["vp lint --lsp<br/>from the declaring package"] A3 -->|No| A5["Stop with an installation hint"] A1 -->|No| A6{"Declared standalone Oxlint<br/>installation found?"} A6 -->|Yes| A8["node selected-script --lsp"] A6 -->|No| A7["Install or update<br/>extension-managed Oxlint"] A7 --> A8 endZed submission note
Copy the note below into the
zed-industries/extensionsupdate PR. Update the source link to the submitted release commit.This update starts
vp lint --lspandvp fmt --lspwithout depending on the legacy tool wrappers. The resolver also supports local, hoisted, and extension-managed installations of standaloneoxlintandoxfmt.The resolver must find the declaring package when a user opens a subpackage of a monorepo. The
WorktreeAPI cannot read ancestor manifests or inspect executable metadata. The extension therefore runs the bundledsrc/binary_resolver/inspect.jsthrough Zed's selected Node runtime.The script checks manifests and installed package entries in the opened directory and its ancestors. It stops at the first workspace marker or the filesystem root. Workspace markers are
pnpm-workspace.yaml,lerna.json, and apackage.jsonwith aworkspacesfield. It also checks explicitvpPathvalues andvpcandidates onPATH, including symlink targets and known executable shims. These reads can extend outside the opened worktree.The inspection script reads files and returns JSON. It does not write files, execute project code, or make network requests. These properties describe the script; the capability does not enforce them.
The manifest uses
command = "*"becausenode_binary_path()returns an absolute path that varies between installations. The matcher cannot match this path by executable name. The fixed mode arguments describe the intended calls, but the wildcard after-epermits arbitrary script text.Haxe uses the same Node invocation pattern. Zed accepted its discovery script as an exception in PR #5611. Our script also checks ancestors and executable metadata, so we request a separate decision for this scope.
We request an exception under the publishing prerequisites for this filesystem discovery helper. Removing it would require reduced discovery support or a new resolution API. If an existing supported API can provide this behavior, please direct us to it.
This implements the detection RFC and follows oxc-vscode#384.