Embedded Nu evaluation ≠ Nu plugin authoring.
Embedded Nushell describes a granted native evaluator called by wasm plugins; it does not define how Nu source becomes a plugin component.
Authors still need a contribution declaration, WIT exports, typed SDK bindings, artifact packaging, build/check/test support.
No end-to-end Nu authoring path was established by this investigation.
Smith Specification: native effect mechanisms separated from plugin-owned tool definitions; offline generated reference plus tested example source.
Rust remains primary; TypeScript remains maintained compatibility target.
Nu authoring support needs an explicit language contract, not silent reinterpretation of those guarantees.
Evidence scope
Desk research only.
Sampled upstream Nu 0.116.0; not an adoption or version-pinning decision.
No build, target-compatibility test, sandbox proof, cost measurement, or source copying performed.
Current WIT exports only declare-tools and JSON invoke; it imports no Nu evaluator or effect interfaces.
Proposed authoring paths cannot be implemented against that unchanged surface.
Upstream distinctions
Nu custom commands provide functions, signatures, documentation, structured pipeline values.1
Rust Command supplies signature, description, evaluation hooks; possible SDK-command integration mechanism, not a Smith ABI.2
nu-engine explicitly identifies itself as an internal Nu crate; Smith must own the facade and upgrade burden.3
Nu compile produces evaluation IR, not a wasm component.4
Native interruption uses cooperative Signals; this alone does not prove parsing, allocation, native-command, or deadline bounds.5
Third-party embedding examples demonstrate selective command registration on Nu 0.108; their sandbox claims are not Smith security evidence.6
Historical upstream browser demo uses wasm-bindgen, JS/browser imports, old Nu APIs, Git dependencies; its last inspected commit is from 2021.7
Nu plugins extend Nu through a version-matched executable protocol; they are not Smith WIT components.8
Candidate paths
Path
Author writes
Contract fit
Unresolved cost or risk
Generated wasm bridge → native Nu SDK facility
Nu handlers plus declarative contributions
Closest to existing native-evaluator intent; ordinary installed component
Inspected upstream compiler emits Nu IR; new compiler and semantic conformance work
External nu or Nu plugin protocol adapter
Scripts or Nu-protocol executables
Not a substitute for the in-process evaluator or Smith component ABI
Interpreter launches, installed-version coupling, separate supervision and protocol
Native source-only .nu plugin loader
Nu source
Violates current prebuilt-component identity and execution contract unless wrapped at explicit build
Requires architectural change; cannot be smuggled in as a language adapter
No measured performance ranking exists.
Guest interpretation remains interpretation; compiling the Rust evaluator into wasm does not compile Nu source ahead of time.
Command allow-listing does not establish native memory isolation or deadline compliance.
Candidate to prove first
Generated wasm bridge around the existing granted native Nu facility.
Reason: contract reuse, not a claimed speed advantage.
Reject this candidate if independent native bounds or effect mediation cannot be proved.
Guest-contained evaluation remains a separate feasibility candidate, not an automatic fallback.
Proposed runtime boundary:
flowchart TB
h["Host dispatch"] --> w["Ordinary wasm bridge"]
w --> n["Granted native Nu facility"]
n --> e["Typed Smith effects"]
The bridge preserves component identity; it does not place Nu computation inside the wasm sandbox.
Nu command registration inside the evaluator implements SDK primitives, never a separate native tool registry.
Authoring and artifact questions
Nu handlers own behavior; generic generated glue owns WIT adaptation, never handwritten Rust per plugin.
Contributions must come from an authoritative source declaration; do not grow manifest statics into a second contribution registry.
Build derives effect-free wasm registration data; registration cannot call the native evaluator before generation publication.
Explicit build packages source and modules inside hash-covered component bytes; no ambient source-file reads or rebuilds at load.
Invoke resolved definitions with typed arguments; never interpolate untrusted input into executable source text.
Define WIT/Nu mappings for records, variants, options, bytes, errors, resources; do not silently reduce every SDK contract to JSON strings.
Resource handles remain host-validated, invocation- and generation-scoped; no unchecked IDs, pointers, or transferable authority.
Clarify runtime Nu parsing/IR compilation versus the existing no-recompile-at-load law before promising a source-containing artifact format.
Immutable compiled declarations may be cached only with complete identity keys; mutable stack, variables, definitions, cwd, environment remain invocation-local.
Parser imports, const evaluation, redirection, externals, jobs, parallel pipelines, clocks, randomness must share controlled effect and budget boundaries.
Cancellation, exhausted budgets, sandbox violations, recording failures cannot become catchable success through Nu try.
Tooling and documentation questions
Language adapter extends existing smith plugin init/build/check/test/dev; Cargo remains build system for generated Rust components.
No installed nu dependency at runtime.
Validation uses Smith's exact exposed evaluator, not an unrelated local shell version.
Generated Rust passes guest lint gates; Nu source needs explicit syntax, type, command-surface, effect, determinism, and runtime tests.
Start with a real tool vertical; do not advertise providers, events, layouts, or modules until their mappings and semantics are tested.
Provider decoding remains pure under the provider contract; an evaluator grant cannot introduce hidden I/O into codec calls.
Two genuine consumers must earn new world interfaces.
SDK reference derives from authoritative WIT/declarations; Nu binding reference derives from the same mapping.
Real packages belong under examples/<name>/; shipped source is not auto-loaded executable configuration.
Offline smith docs covers authoring, bindings, supported Nu semantics, diagnostics, complete tested source; bounded retrieval only.
Proof required before implementation approval
Resolve authoring contract gaps through explicit spec approval; no spec edits implied by this issue.
Build and load two real Nu-authored consumers without handwritten Rust handlers or installed Nu.
Nu plugins; live documentation describing Nu's executable protocol, not Smith's WIT world. ↩
---
id: SMH-ISSUE-2Y6OFOWN
type: issue
title: "Nushell Plugin Authoring Path"
specs: [SMH-SPEC-SPEC0001, SMH-SPEC-PLUG0001, SMH-SPEC-WASM0001, SMH-SPEC-ZVMD_XYT]
---
# Nushell Plugin Authoring Path
## Gap
Embedded Nu evaluation ≠ Nu plugin authoring.
[Embedded Nushell](../../specs/SMH-SPEC-ZVMD_XYT-embedded-nushell/index.md) describes a granted native evaluator called by wasm plugins; it does not define how Nu source becomes a plugin component.
Authors still need a contribution declaration, WIT exports, typed SDK bindings, artifact packaging, build/check/test support.
No end-to-end Nu authoring path was established by this investigation.
## Existing contracts
- [Plugin System](../../specs/SMH-SPEC-PLUG0001-plugin-system/index.md): ordinary components, effect-free registration, atomic generations, shared child budgets, no privileged built-in path.
- [Wasm Plugin Runtime](../../specs/SMH-SPEC-WASM0001-wasm-plugin-runtime/index.md): prebuilt component plus KDL manifest, artifact hashes, no rebuild at load, sealed imports, language-adapter tooling.
- [Embedded Nushell](../../specs/SMH-SPEC-ZVMD_XYT-embedded-nushell/index.md): invocation-local native evaluation, no installed interpreter, independent native bounds, controlled effects.
- [Smith Specification](../../specs/SMH-SPEC-SPEC0001-smith-specification/index.md): native effect mechanisms separated from plugin-owned tool definitions; offline generated reference plus tested example source.
Rust remains primary; TypeScript remains maintained compatibility target.
Nu authoring support needs an explicit language contract, not silent reinterpretation of those guarantees.
## Evidence scope
Desk research only.
Sampled upstream Nu 0.116.0; not an adoption or version-pinning decision.
No build, target-compatibility test, sandbox proof, cost measurement, or source copying performed.
[Current WIT](../../../wit/smith-plugin.wit) exports only `declare-tools` and JSON `invoke`; it imports no Nu evaluator or effect interfaces.
Proposed authoring paths cannot be implemented against that unchanged surface.
### Upstream distinctions
- Nu custom commands provide functions, signatures, documentation, structured pipeline values.[^custom]
- Rust `Command` supplies signature, description, evaluation hooks; possible SDK-command integration mechanism, not a Smith ABI.[^command]
- `nu-engine` explicitly identifies itself as an internal Nu crate; Smith must own the facade and upgrade burden.[^engine]
- Nu `compile` produces evaluation IR, not a wasm component.[^compile]
- Native interruption uses cooperative `Signals`; this alone does not prove parsing, allocation, native-command, or deadline bounds.[^signals]
- Third-party embedding examples demonstrate selective command registration on Nu 0.108; their sandbox claims are not Smith security evidence.[^embed]
- Historical upstream browser demo uses `wasm-bindgen`, JS/browser imports, old Nu APIs, Git dependencies; its last inspected commit is from 2021.[^demo]
- Nu plugins extend Nu through a version-matched executable protocol; they are not Smith WIT components.[^plugins]
## Candidate paths
| Path | Author writes | Contract fit | Unresolved cost or risk |
| --- | --- | --- | --- |
| Generated wasm bridge → native Nu SDK facility | Nu handlers plus declarative contributions | Closest to existing native-evaluator intent; ordinary installed component | Native author logic lies outside wasm fuel and memory; independent bounds mandatory |
| Nu evaluator compiled into each guest component | Nu handlers; generated Rust embedding glue | Author computation remains under wasm fuel and memory | Nu 0.116 target support, sealed imports, fixed memory, interpreter placement unproven |
| Nu → Rust/wasm ahead-of-time compiler | Nu source | Could produce ordinary components | Inspected upstream compiler emits Nu IR; new compiler and semantic conformance work |
| External `nu` or Nu plugin protocol adapter | Scripts or Nu-protocol executables | Not a substitute for the in-process evaluator or Smith component ABI | Interpreter launches, installed-version coupling, separate supervision and protocol |
| Native source-only `.nu` plugin loader | Nu source | Violates current prebuilt-component identity and execution contract unless wrapped at explicit build | Requires architectural change; cannot be smuggled in as a language adapter |
No measured performance ranking exists.
Guest interpretation remains interpretation; compiling the Rust evaluator into wasm does not compile Nu source ahead of time.
Command allow-listing does not establish native memory isolation or deadline compliance.
## Candidate to prove first
Generated wasm bridge around the existing granted native Nu facility.
Reason: contract reuse, not a claimed speed advantage.
Reject this candidate if independent native bounds or effect mediation cannot be proved.
Guest-contained evaluation remains a separate feasibility candidate, not an automatic fallback.
Proposed runtime boundary:
```mermaid
flowchart TB
h["Host dispatch"] --> w["Ordinary wasm bridge"]
w --> n["Granted native Nu facility"]
n --> e["Typed Smith effects"]
```
The bridge preserves component identity; it does not place Nu computation inside the wasm sandbox.
Nu command registration inside the evaluator implements SDK primitives, never a separate native tool registry.
### Authoring and artifact questions
- Nu handlers own behavior; generic generated glue owns WIT adaptation, never handwritten Rust per plugin.
- Contributions must come from an authoritative source declaration; do not grow manifest statics into a second contribution registry.
- Build derives effect-free wasm registration data; registration cannot call the native evaluator before generation publication.
- Explicit build packages source and modules inside hash-covered component bytes; no ambient source-file reads or rebuilds at load.
- Invoke resolved definitions with typed arguments; never interpolate untrusted input into executable source text.
- Define WIT/Nu mappings for records, variants, options, bytes, errors, resources; do not silently reduce every SDK contract to JSON strings.
- Resource handles remain host-validated, invocation- and generation-scoped; no unchecked IDs, pointers, or transferable authority.
- Clarify runtime Nu parsing/IR compilation versus the existing no-recompile-at-load law before promising a source-containing artifact format.
- Immutable compiled declarations may be cached only with complete identity keys; mutable stack, variables, definitions, cwd, environment remain invocation-local.
- Parser imports, const evaluation, redirection, externals, jobs, parallel pipelines, clocks, randomness must share controlled effect and budget boundaries.
- Cancellation, exhausted budgets, sandbox violations, recording failures cannot become catchable success through Nu `try`.
### Tooling and documentation questions
Language adapter extends existing `smith plugin init/build/check/test/dev`; Cargo remains build system for generated Rust components.
No installed `nu` dependency at runtime.
Validation uses Smith's exact exposed evaluator, not an unrelated local shell version.
Generated Rust passes guest lint gates; Nu source needs explicit syntax, type, command-surface, effect, determinism, and runtime tests.
Start with a real tool vertical; do not advertise providers, events, layouts, or modules until their mappings and semantics are tested.
Provider decoding remains pure under the provider contract; an evaluator grant cannot introduce hidden I/O into codec calls.
Two genuine consumers must earn new world interfaces.
SDK reference derives from authoritative WIT/declarations; Nu binding reference derives from the same mapping.
Real packages belong under `examples/<name>/`; shipped source is not auto-loaded executable configuration.
Offline `smith docs` covers authoring, bindings, supported Nu semantics, diagnostics, complete tested source; bounded retrieval only.
## Proof required before implementation approval
- [ ] Resolve authoring contract gaps through explicit spec approval; no spec edits implied by this issue.
- [ ] Build and load two real Nu-authored consumers without handwritten Rust handlers or installed Nu.
- [ ] Demonstrate ordinary registration, trust, grants, artifact hashing, failed-load rollback, atomic reload, active-generation pinning.
- [ ] Prove parser and command paths cannot escape effects through files, network, processes, environment, clock, randomness, or startup configuration.
- [ ] Prove independent native bounds across parsing, loops, recursion, streams, allocations, conversion, output; cancellation remains uncatchable.
- [ ] Prove invocation and plugin isolation; replay repeats no external mutations.
- [ ] Exercise exact exposed language and SDK bindings through built Smith with real files and supervised processes.
- [ ] Compare matching cold/warm workloads for native-bridge and guest-contained candidates: allocations, instructions, artifact bytes, startup, retained memory; wall clock only as same-machine evidence.
- [ ] Ship checked example packages and offline language/SDK reference with pinned provenance and license review.
## Sources
[^custom]: [Nu custom commands](https://www.nushell.sh/book/custom_commands.html); live documentation, not a pinned release contract.[^command]: [Nu 0.116.0 `Command`](https://github.com/nushell/nushell/blob/0.116.0/crates/nu-protocol/src/engine/command.rs).[^engine]: [Nu 0.116.0 engine API](https://docs.rs/nu-engine/0.116.0/nu_engine/).[^compile]: [Nu 0.116.0 compiler API](https://docs.rs/nu-engine/0.116.0/nu_engine/fn.compile.html).[^signals]: [Nu 0.116.0 interruption API](https://docs.rs/nu-protocol/0.116.0/nu_protocol/struct.Signals.html).[^embed]: [Embedding guide, commit `07b212a992cebdfbafd7c75f1b9b6b8eb3113e78`](https://github.com/cablehead/how-to-embed-nu/tree/07b212a992cebdfbafd7c75f1b9b6b8eb3113e78); inspected root manifest and restricted-environment README, not executed.[^demo]: [Browser demo, commit `3fccd11c2af42127d177f6e77f6dc58768c91b91`](https://github.com/nushell/demo/tree/3fccd11c2af42127d177f6e77f6dc58768c91b91); inspected manifest and `src/lib.rs`, not executed.[^plugins]: [Nu plugins](https://www.nushell.sh/book/plugins.html); live documentation describing Nu's executable protocol, not Smith's WIT world.