Expand description
Post-install setup-script execution.
When a plugin manifest declares a setup script, the marketplace
install flow auto-runs it after the plugin’s source is in place.
This is how source-shipped plugins (e.g. ones that ship a Rust
crate and need cargo build --release to produce the binary
[extension.command] points at) get built without forcing the
user to run scripts/setup.sh by hand.
Two manifest slots are recognised, in priority order:
extension.setup— the extension’s own build script. Checked first because the extension binary is what the host will spawn immediately on session start.provides.sidecar.setup— the sidecar’s build script (legacy slot; still honoured for sidecar-only plugins).
At most one script runs per install. Plugins that ship both an
extension and a sidecar from one repo should drive both builds
from a single scripts/setup.sh referenced via extension.setup.
§Security
Setup scripts are arbitrary shell. We mitigate by:
- Refusing setup paths that escape the plugin dir (
.., absolute). - Refusing setup paths that don’t resolve (canonicalize) inside the plugin dir.
- Requiring the script file exists and is executable.
- Capping wall-clock runtime at
SETUP_TIMEOUT. - Capturing stdout+stderr to a per-install log (no swallowing).
§Failure mode
A failed setup script does not roll back the install — the source is on disk and the user can rerun the script manually. The caller surfaces the failure to the UI with a pointer to the log file.
Pure helpers live here so they can be unit-tested without a real
tokio runtime; the async runner is a thin shell over
tokio::process::Command.
Structs§
- Setup
Outcome - Outcome of a successful setup-script run.
Enums§
- Command
Verify Error - Why an extension command verification failed. Distinct from
SetupErrorbecause the failure mode and remediation are different — here, the build “succeeded” but the artifact the manifest promised isn’t there. - Prebuilt
Error - Why a prebuilt-binary install attempt failed. Variants distinguish “no asset for this host” (caller falls back to the setup script) from “asset matched but couldn’t be installed” (caller surfaces the error — security failures and network issues should not silently trigger a build).
- Setup
Error - Why a setup script could not be run, or why it failed once started.
Constants§
- MAX_
PREBUILT_ ARCHIVE_ BYTES - Stable host-triple string used as the lookup key in
crate::extensions::manifest::ExtensionManifest::prebuilt. We intentionally use a compact<os>-<arch>form (e.g.linux-x86_64,darwin-arm64,windows-x86_64) rather than full Rust target triples (x86_64-unknown-linux-gnu) because plugin authors hand-write these strings into JSON manifests — readability - SETUP_
TIMEOUT - Wall-clock cap on a single setup script. Sample from-scratch builds run ~5 minutes on a modern dev box; 10 minutes leaves a healthy margin for slower CI/older hardware without making a runaway script wedge the install flow forever.
Functions§
- host_
triple - install_
log_ path - Build the per-install log path. Caller is expected to create the parent directory before opening it. Format:
- normalize_
sha256 - Normalize SHA-256 manifest values to lower-case hex. Rejects anything other than exactly 64 ASCII hex characters.
- resolve_
setup_ script - Resolve the manifest-declared setup script to an absolute path
inside
plugin_dir, or returnOk(None)if no setup is declared. - run_
setup_ script - Run the resolved setup script against
plugin_dir, streaming combined stdout+stderr tolog_path. Returns on success, exit code, timeout, or I/O error. - safe_
name_ fragment - Sanitize a manifest-controlled string before using it as a filename fragment
or displaying it in terse user-facing hints. Unsafe/control characters become
_; empty/all-unsafe input becomesplugin. - try_
install_ from_ prebuilt - Try to install the extension binary from
crate::extensions::manifest::ExtensionManifest::prebuiltfor the current host. Lookup is byhost_triple. - verify_
extension_ command - Verify that the extension binary declared by
crate::extensions::manifest::ExtensionManifest::commandactually exists and is executable insideplugin_dir. Used as the post-condition check afterrun_setup_scriptsucceeds, so a build script that exits 0 but doesn’t produce the promised binary surfaces a clear error instead of silently breaking spawn at runtime.