Файли
openidea/wit/workspace.wit
T
arookieofc 303d5950bf fix(plugin): report missing files as not-found and add project exists/stat (#1964)
* fix(plugin): report missing files as not-found and add project exists/stat

read-file of a missing path now returns error::not-found in the host,
matching the SDK mock, instead of error::invalid. project gains
exists(path) for a cheap existence check (files and directories, hidden
and ignored included) and stat(path) for kind/size/modified, both
gated by project.read and refusing paths outside the root.

Fixes #1957

* chore: silence clippy in sandbox test and rebuild plugin components

- drop an unnecessary to_path_buf clippy flags on unix
- rebuild every checked-in plugin.wasm: the SDK and wit/ changed, so
  their source fingerprints moved

* test(plugin): cover missing-file not-found and fix CRLF-only Windows failure
2026-11-07 18:01:33 +08:00

126 рядки
4.8 KiB
Plaintext

package openidea:[email protected];
interface workspace {
use types.{error};
/// What a path inside a project is.
enum file-kind {
file,
directory,
symlink,
other,
}
/// Metadata of a path inside a project, as `stat` reports it.
record file-stat {
kind: file-kind,
/// Bytes, for a file.
size: u64,
/// Seconds since the Unix epoch; `none` when the file system does
/// not track it.
modified: option<u64>,
}
/// A project open in the IDE.
resource project {
/// Absolute path of the project root. Requires `project.read`.
root: func() -> result<string, error>;
/// Reads a UTF-8 text file inside the project (absolute, or relative
/// to the root); paths leaving the root are refused. Unsaved editor
/// contents win over the disk. A missing path is `not-found`.
/// Requires `project.read`.
read-file: func(path: string) -> result<string, error>;
/// Whether `path` (absolute, or relative to the root) names an
/// existing file or directory — including hidden and ignored ones,
/// without reading any content. Paths leaving the root are refused.
/// Requires `project.read`.
exists: func(path: string) -> result<bool, error>;
/// Metadata of an existing path inside the project (absolute, or
/// relative to the root); a missing path is `not-found` and paths
/// leaving the root are refused. Requires `project.read`.
stat: func(path: string) -> result<file-stat, error>;
/// Project files whose root-relative path matches `glob` (`**/*Mapper.xml`),
/// at most `limit`, as absolute paths. Ignored and excluded files are
/// skipped. Requires `project.read`.
find-files: func(glob: string, limit: u32) -> result<list<string>, error>;
}
/// Projects open in any window. Requires `project.read`.
projects: func() -> result<list<project>, error>;
}
interface editor {
use types.{error, range, text-edit};
record document {
/// Grows with every change; edits name the version they were made for.
version: u64,
text: string,
}
/// A file open in an editor.
resource text-editor {
/// Absolute path of the file.
path: func() -> string;
/// Language id (`rust`, `solidity`, …).
language: func() -> string;
/// Current version and text. Requires `editor.read`.
document: func() -> result<document, error>;
/// Selections when the command was invoked (a cursor is an empty
/// range). Requires `editor.read`.
selections: func() -> result<list<range>, error>;
/// Applies `edits` as one undoable change, only if the document is
/// still at `version` (else `stale`, and nothing changes). Ranges are
/// in that version and must not overlap. Returns the new version.
/// Requires `editor.write`.
apply-edits: func(version: u64, edits: list<text-edit>) -> result<u64, error>;
}
}
/// Where a command or event comes from.
interface invocation {
use workspace.{project};
use editor.{text-editor};
resource invocation {
/// The window's project.
project: func() -> option<project>;
/// The window's focused editor.
editor: func() -> option<text-editor>;
/// The files and folders the command was run on (a multi-selection in
/// a file tree, for instance), as absolute paths.
/// Empty when it was not run on any, or when the menu was for a tab
/// without a file (a virtual document).
selected-paths: func() -> list<string>;
}
}
/// Git, for the repository containing a project.
interface vcs {
use types.{error};
use workspace.{project};
record repository-status {
/// Absolute path of the working tree root.
root: string,
/// `none` when HEAD is detached.
branch: option<string>,
commit: option<string>,
upstream: option<string>,
ahead: u32,
behind: u32,
/// Merge / rebase / cherry-pick in progress.
operation: option<string>,
/// Files with staged or unstaged changes.
changed-files: u32,
}
/// `none` when the project is not in a repository. Requires `vcs.read`.
status: func(project: borrow<project>) -> result<option<repository-status>, error>;
/// Configured remotes (`name`, fetch `url`), in order. Requires `vcs.read`.
remotes: func(project: borrow<project>) -> result<list<tuple<string, string>>, error>;
/// Fetches all remotes (pruning deleted branches). Requires `vcs.write`.
/// Long-running: call it inside a task.
fetch: func(project: borrow<project>) -> result<_, error>;
}