github.com/nevalang/neva
v0.41.0
#1569 most downloaded on Go modules
nevalang/neva
What this package is like to depend on
Last release 19 days ago
05 Aug 2026
Ships fairly regularly
a new release about every 3 weeks
Rarely documented
notes for 10 of 57 stable releases
Nothing withdrawn
no release was ever pulled
3 years old
101 releases · first in 2024
24 releases in the last 12 months
see the full history below
Release timeline
101 releases · Jan 2024 to Aug 2026Releases
latest 60 of 101-
v0.41.005 Aug 2026Release notes
Open source →Canonical Flow
Compared to v0.40.0, Neva v0.41.0 establishes one canonical, zero-config format for Neva source, exposes that formatter both through the CLI and a public Go package, adds a portable type-description substrate for future runtime tooling, and hardens several runtime and installation paths.
Highlights
neva fmtis now built into the Neva CLI. It formats valid Neva source with one fixed, syntax-only style and is available for stdin, files, and recursively scanned directories.- The public Go package
pkg/formatterprovides the same formatter to tools and integrations. It parses and renders standalone Neva source without module resolution, analysis, desugaring, or code generation. - The formatter canonicalizes import blocks and composite literals, wraps breakable layouts at 80 columns, and is checked against the repository source corpus in CI.
std/reflect.TypeandTypeNodeexpose a portable finite, indexed description of a Neva type. Recursive edges are represented as indexes into the same descriptor.Turn,Match, andSelectnow receive independent inputs concurrently, eliminating the sequential-receive deadlock risk when senders arrive in a different order.- The Unix installer no longer requires
sudo; setNEVA_INSTALL_DIRto choose an explicit destination.
A first-party, zero-config formatter
Use
neva fmtbefore committing, or make it a repository gate:neva fmt -w . neva fmt --check .
neva fmtis deliberately opinionated and has zero configuration: each valid source file has exactly one canonical layout. It is syntax-preserving, so semantic style rules and automated refactorings remain separate tooling concerns.The design drew on
gofmt,rustfmt, Prettier, Kotlin, Swift, Zig, and Odin formatters, while settling on Neva's own canon: compact layouts where they remain readable, vertical sequences when they do not, and no ambiguous alternatives for imports, indentation, or spacing.For example, it sorts imports into their canonical groups and normalizes indentation:
Before
import { @:zeta third:omega fmt @:alpha third:alpha reflect third:zeta @:omega runtime }After
import { fmt reflect runtime third:alpha third:omega third:zeta @:alpha @:omega @:zeta }It also makes a single deterministic choice when a breakable sequence crosses 80 columns:
Before
type ExtremelyLongAlias very_long_package.SomeVeryLongGeneric<first_type, second_type, third_type> interface VeryLongInterfaceName<first_very_long_type_parameter, second_very_long_type_parameter, third_very_long_type_parameter> () ()After
type ExtremelyLongAlias very_long_package.SomeVeryLongGeneric< first_type, second_type, third_type, > interface VeryLongInterfaceName< first_very_long_type_parameter, second_very_long_type_parameter, third_very_long_type_parameter, >() ()For scripting and editor integration, the command supports standard output, in-place writes, diffs, file listing, parse-error continuation, and deterministic directory traversal:
neva fmt -d path/to/file.neva neva fmt -l .Go-based tools can import the same public package used by the CLI:
import "github.com/nevalang/neva/pkg/formatter" formatted, err := formatter.Format(source)
Portable type descriptors: a foundation for future tooling
std/reflect.Typeis a compact graph representation for carrying a resolved Neva type as data. Its public shape is a list ofTypeNodevalues; the relevant node forms include scalar values and indexes to composite children:pub type Type list<TypeNode> pub type TypeNode union { String List int Struct list<StructField> Union list<UnionCase> }The root is node
0; composite relationships point to other nodes by index. For example, the Neva typelist<string>is carried at runtime as:const list_of_strings reflect.Type = [ reflect.TypeNode::List(1), reflect.TypeNode::String, ]This makes recursive types representable without a global registry or per-message metadata.
This release deliberately provides the descriptor substrate only: it is a foundation for future reflection-aware tooling. It does not add
TypeOf,#bind_type, JSON conversion, or a global type registry.Reliability and developer experience
Turn,Match, andSelectpreserve their existing behavior while accepting independent inputs in either sender order.- The installer uses a user-writable location by default and reports release-discovery and download failures correctly.
- Node and declaration syntax, documentation, and the checked-in source corpus were aligned with the new canonical formatter output.
Included PRs
- #1166 Install Neva without
sudo - #1169 Remove comma-separated node and import declarations
- #1173 Structure compiler directives in the AST
- #1175 Add the portable
std/reflecttype descriptor - #1180 Receive runtime inputs concurrently
- #1172, #1174, #1177, #1178, #1181, #1183, #1184, #1185, #1186, and #1188 First-party formatter and its canonical CI baseline
- #1189, #1190, and #1191 Documentation, CI, and release maintenance
Full Changelog
-
v0.40.1-0.20260805061830-bb7b3301b46105 Aug 2026 pre-releaseNothing published for this version
-
v0.40.031 Jul 2026Release notes
Open source →Tidal Threads
Compared to v0.39.0, Neva v0.40.0 redesigns streams as an explicit tagged-union protocol, expands immutable list operations, and makes common scalar collections materially faster without changing their public Neva types.
Highlights
stream<T>is now the tagged unionOpen | Data T | Close, rather than a struct carrying an implicit index and terminal flag. Stream boundaries and payloads are explicit, and an index is created only when a program asks for one withstreams.Enumerate<T>.streams.Just<T>adapts one value to a stream, whilestreams.Enumerate<T>adds explicit zero-based indexes when they are needed.lists.Append<T>is the renamedlists.Push<T>operation. Together with newPrepend<T>andConcat<T>, it provides immutable list updates.- Scalar
list<T>anddict<T>values now use native typed runtime storage where possible. Scalar-list traversal is 75–87% faster; constructing a 512-int list is 82% faster, uses 64% less memory, and makes 255 fewer allocations. neva tool <name>provides a consistent CLI entry point for an installedneva-*developer tool, includingneva tool lsp.- Compiler-version mismatch errors now name the workspace module, point to its
neva.ymlorneva.yaml, and recommendneva upgrade.
Streams: a model with explicit states
Previously, every item in a
stream<T>carried control metadata even when a program only needed the value:pub type stream<T> struct { data T idx int last bool }Now a stream is a tagged union with exactly three possible states:
pub type stream<T> union { Open Data T Close }Openmarks the beginning of a stream,Datacarries a value, andClosemarks completion. Sources such asstreams.Range,streams.FromList, andstreams.Justemit this protocol; ordinary user code normally passes streams to standard combinators rather than handling the three cases itself.This is Neva's return to the canonical FBP stream design: bracket information packets delimit a sequence of ordinary data packets. It follows the model described by FBP pioneer J. Paul Morrison, with whom Neva's author corresponded while developing the language. The earlier indexed structure was an intermediate design; experience showed that the explicit FBP protocol is the more idiomatic and robust model.
streams.Map,Filter,ForEach, and other combinators useSwitch<stream<T>>internally: they forwardOpen, transform or handleData, and forwardClose. The three paths are intentionally shown only as a schematic here — the actualMapgraph also has aFanInand ordering/backpressure wiring that must not be omitted:Open -> ... -> Open Data -> handler -> Data Close -> ... -> CloseThe model makes the protocol visible in the type system, removes a stored index from the default representation, and keeps indexing as an opt-in operation.
streams.Just<T>pub def Just<T>(data T) (res stream<T>)Justadapts one value to an API that expects a stream. Given42, it emitsOpen,Data(42), thenClose.This matters when a higher-level API is stream-oriented but the caller has one value. For example, the PNG example creates one
image.Pixel, turns it into a one-item stream withJust, and passes that stream toimage.New:new image.New just streams.Just<image.Pixel> --- newPixel -> just -> newstreams.Enumerate<T>pub type Enumerated<T> struct { idx int item T } pub def Enumerate<T>(data stream<T>) (res stream<Enumerated<T>>)Use
Enumeratewhen an index is part of the program's logic. It attaches0,1,2, … toDataitems instead of making every stream item retain an index by default.std/listsThis release adds three list operations. As with the rest of Neva's value operations, each returns a new list; the input list is not mutated.
lists.Append<T>— renamed fromPush<T>pub def Append<T>(lst list<T>, data T) (res list<T>)The dataflow below appends
3to[1, 2]and produces[1, 2, 3].append lists.Append<int> --- [1, 2] -> append:lst 3 -> append:data append:res -> :res // produces [1, 2, 3]lists.Prepend<T>pub def Prepend<T>(lst list<T>, data T) (res list<T>)Prepending
1to[2, 3]produces[1, 2, 3].lists.Concat<T>pub def Concat<T>(left list<T>, right list<T>) (res list<T>)Joining
[1, 2]and[3, 4]produces[1, 2, 3, 4].concat lists.Concat<int> --- [1, 2] -> concat:left [3, 4] -> concat:right concat:res -> :res // produces [1, 2, 3, 4]Faster scalar lists and dictionaries
This release includes a runtime optimization for common scalar collections. On the measured hot path, scalar-list traversal is 75–87% faster; constructing a 512-int list is 82% faster and uses 64% less memory. At the language level,
list<T>anddict<T>are unchanged.Internally, homogeneous scalar values no longer have to be stored as a generic runtime-message box per element when a typed representation is available.
Conceptually, the runtime can now keep an integer list or dictionary in native typed storage:
before: []Msg{Int(1), Int(2), Int(3)} after: []int64{1, 2, 3} before: map[string]Msg{"answer": Int(42)} after: map[string]int64{"answer": 42}Heterogeneous and non-scalar values retain the existing generic representation. The runtime boxes values only at boundaries that actually require generic messages.
On an Apple M1 Pro with Go 1.26.5, the benchmarked implementation delivers:
- scalar-list traversal: 75–87% faster for 8–1024 integer items;
- construction of a 512-int list: 82% faster, 64% fewer bytes, and 255 fewer allocations;
- construction of a 512-int dictionary: 10.6% faster, 33.7% fewer bytes, and 255 fewer allocations;
- full
list_atandlist_slicepaths: 3–4% faster with one to two fewer allocations; - dictionary lookup: neutral in the full port path; no regression observed.
The detailed benchmark method and raw comparison are in PR #1127.
Developer tools
Run an installed language server through the Neva CLI:
neva tool lsp
neva toolis a dispatcher for installed executables namedneva-<name>; it does not install or update tools itself.Smaller developer-experience improvements
- Compiler-version mismatch errors now identify the affected workspace module, show where its declared version lives, and suggest
neva upgrade. - Tagged-union documentation now matches the compiler: declare tagged
union { ... }types rather than the removed untagged-union syntax.
Included PRs
- #1042 Redesign stream as union and add
streams.Enumerate - #1047 Redesign stream item helpers and enumerate support
- #1127 Typed scalar list/dict containers and runtime fast paths
- #1144 Validate union literal payloads
- #1151, #1153, #1154, #1155, #1157 Runtime message and collection work
- #1158 CLI developer-tool manager
- #1161 Tagged-union documentation correction
- #1162 Compiler-version mismatch guidance
Documentation, CI, benchmark, and engineering-harness improvements in the same release window are included as maintenance work.
Full Changelog
-
v0.39.006 Jul 2026Release notes
Open source →Operating Handles
Compared to v0.38.0, this release expands the standard library with practical OS and file-handle capabilities, improves parser error handling, and tightens release/version maintenance.
Summary
- Added explicit
std/iofile handles:File,Open,Create,Close,ReadAllFile, andWriteAllFile. - Existing filename-based
std/io.ReadAllandstd/io.WriteAllremain available as convenience APIs for whole-file reads and writes. - Expanded
std/oswith typed environment, process, filesystem, and temp-path primitives. - Fixed
std/os.Argsruntime list construction. - Parser recovery now returns compiler errors for missing connection/sender/receiver sides instead of panicking.
- Release prep now bumps repository version references consistently across manifests, docs, generated headers, and tests.
- Repository AI harness assets were consolidated under
.codex/.
Standard library: file handles
std/ionow supports explicit open/create/read/write/close flows for programs that need to keep file access state visible in the graph.import { bytes, io } def WriteExample(start any) (stop any, err error) { create io.Create? from_string bytes.FromString write io.WriteAllFile? close io.Close? --- :start -> [ 'out.txt' -> create:filename, 'hello' -> from_string:data ] from_string:res -> write:data create:res -> write:file write:res -> close:file close:res -> :stop }Standard library: OS primitives
std/osnow covers common environment, process, filesystem, and temporary-path operations through typed, dataflow-friendly components. Query-style components are signal-triggered so programs stay explicit about when OS data is read.import { os } def ListCwd(start any) (res list<os.DirEntry>, err error) { getwd os.Getwd? read_dir os.ReadDir? --- :start -> getwd:sig getwd:res -> read_dir:path read_dir:res -> :res }Parser and runtime reliability
- Malformed connection shapes that previously could panic during parser recovery now produce
compiler.Error. - File-handle runtime paths include lifecycle and registry coverage.
- New
std/osruntime helpers are covered by targeted unit and e2e tests.
Internal and tooling notes
- Version references were synchronized to
0.39.0across checked-in manifests, examples, docs, generated headers, and test expectations. - The
release-nevaskill now documents repo-wide version bump requirements. - Legacy
.agent,.claude/rules, and.opencodeharness roots were consolidated under.codex/.
Included PRs
- #1139 fix(parser): return compiler errors for missing conn sides
- #1141 [codex] consolidate AI harness
- #1040 stdlib/io: add explicit Open/Create/Close file-handle API
- #1041 Implement std/os package for env/process/fs primitives
- #1143 release: bump version to v0.39.0
Full Changelog
- Added explicit
-
v0.38.031 May 2026Release notes
Open source →Typed Waters
Compared to v0.37.1, this release makes generic node usage stricter and more explicit, improves runtime safety around edge cases, and continues internal tooling groundwork.
Summary
- Generic node instantiations now require explicit type arguments (implicit
anyfallback removed). - Added analyzer + e2e regression coverage so this rule cannot silently regress.
- Runtime safety improved for
list_atout-of-bounds flow andArrayInport.Selectbehavior. pkg/viewnow exposes port order and DI args for downstream visual/tooling work.- Runtime microbench suite expanded for scalar list/dict message paths.
- Docs now clarify
anysemantics and container specialization policy.
Language change: explicit generic args for nodes
This change is specifically about generic nodes at initialization/callsites.
If a node is generic, pass<T>explicitly when you instantiate it.Before (now invalid, missing type arg):
import { fmt runtime } def Main(start any) (stop any) { println fmt.Println panic runtime.Panic --- :start -> "hello" -> println:data println:res -> :stop println:err -> panic }After (valid):
import { fmt runtime } def Main(start any) (stop any) { println fmt.Println<string> panic runtime.Panic --- :start -> "hello" -> println:data println:res -> :stop println:err -> panic }Internal and tooling notes
- Deterministic projection/ordering guardrails in
viewtests were strengthened. - Version references were synchronized to
0.38.0across release-related files. - Release process docs/harness were tightened for draft-first delivery and explicit publish approval.
Included PRs
- #1130 view: deterministic overload ordering guard + plan sync
- #1131 runtime: expand Msg scalar list/dict microbench coverage
- #1132 analyzer: remove implicit any default for generic node instantiations
- #1133 analyzer: add regression tests for explicit generic node args
- #1134 docs: clarify any and container specialization policy
- #1135 runtime: add safe Select/list_at coverage and fix bounds panic
- #1136 feat(view): expose port order and DI args
- #1137 release: bump version to v0.38.0
Full Changelog
- Generic node instantiations now require explicit type arguments (implicit
-
v0.37.2-0.20260528203050-0e10040527f328 May 2026 pre-releaseNothing published for this version
-
v0.37.2-0.20260528150425-7a5637b7a00628 May 2026 pre-releaseNothing published for this version
-
v0.37.116 May 2026Release notes
Open source →Trace Output Polish
Patch release after
v0.37.0focused on trace output consistency and JSONL cleanup.What changed
- Panic trace rendering aligned with the new pretty tree view (
receiver <- sender, branch lines). - Runtime
newnow propagates signal causes, so causal chains can reach:start. - JSONL trace events omit
port.Indexwhen it isnull(kept only for array ports). - Added focused runtime tests for cause propagation and JSONL encoding behavior.
Included PRs
- Panic trace rendering aligned with the new pretty tree view (
-
v0.37.016 May 2026Release notes
Open source →The Last Mile Begins
Compared to v0.36.1, this release starts the final language-completion track: runtime tracing first, then visual tooling, then debugger stack.
Summary
- Added runtime tracing for panic termination paths.
- Standardized real-time trace file output to JSONL.
- Added
pkg/viewfoundation primitives for upcoming visual tooling.
Why this matters
In control-flow languages, production failures are explained by stack traces.
In Neva, execution is dataflow, so failure context is a causality graph of messages. This release makes that graph observable in runtime output.Runtime Tracing
When panic happens, Neva now prints a panic cause dataflow trace to stderr.
Example A — minimal panic flow
import { fmt runtime } def Main(start any) (stop any) { panic runtime.Panic printf fmt.Printf --- :start -> [ 'value=$1' -> printf:tpl, 10 -> printf:args[0] ] printf:err -> panic printf:sig -> :stop }Pretty trace view (target format):
panic:data <- printf:err ├─ printf:args[0] <- __newv2__2 │ └─ __newv2__2 <- :start └─ printf:tpl <- __newv2__1 └─ __newv2__1 <- :startExample B — branched causes converging into one panic
import { fmt runtime strconv } def Main(start any) (stop any) { panic runtime.Panic printf fmt.Printf left_atoi strconv.Atoi right_atoi strconv.Atoi --- :start -> [ 'left=$0 right=$1 extra=$2' -> printf:tpl, '10' -> left_atoi, '20' -> right_atoi ] [left_atoi:err, right_atoi:err, printf:err] -> panic left_atoi:res -> printf:args[0] right_atoi:res -> printf:args[1] printf:sig -> :stop }Pretty trace view (target format):
panic:data <- __fan_in__2 └─ __fan_in__2:data[2] <- printf:err ├─ printf:tpl <- __newv2__7 │ └─ __newv2__7 <- :start ├─ printf:args[0] <- left_atoi:res │ └─ left_atoi:data <- __newv2__8 │ └─ __newv2__8 <- :start └─ printf:args[1] <- right_atoi:res └─ right_atoi:data <- __newv2__9 └─ __newv2__9 <- :startNote:
Current runtime output still exposes internal synthetic node names (for example__newv2__*) and may stop short of:startfor some runtime funcs. The next tracing patch will align runtime output with the target view above.JSONL Trace Files
Trace events written to file are standardized as JSONL (
v=2, one event per line).Real sample from
trace.log:{"message":{},"port":{"Path":"","Port":"start"},"event":"sent","causeIndexes":null,"v":2,"index":1} {"message":"value=$1","port":{"Path":"__newv2__1","Port":"res"},"event":"sent","causeIndexes":null,"v":2,"index":4} {"message":"value=$1","port":{"Path":"printf","Port":"tpl"},"event":"recv","v":2,"index":4} {"message":10,"port":{"Path":"printf","Port":"args","Index":0},"event":"recv","v":2,"index":5}Visual Tooling Foundation
This release also includes initial
pkg/viewprojection primitives used by the read-only visual tooling track.Related work
Support the project
- Open Collective: https://opencollective.com/nevalang
- Star the repo: https://github.com/nevalang/neva
-
v0.36.122 Apr 2026Release notes
Open source →Maintenance Throughput
The previous "Engineered Stability" release
v0.36.0tightened delivery quality gates.v0.36.1is a focused patch release that continues this maintenance track: wider runtime operator coverage, benchmark surface expansion, lint debt reduction, and CI/release automation cleanup.🌟 Summary
- Added missing runtime builtin coverage for unary negate and slice operator paths.
- Fixed delayed-echo example wait-group accounting to prevent hanging behavior.
- Expanded runtime benchmark coverage (foundation, support-wired, simple operators, and atomic builtin batches).
- Continued strict
golangci-lintrollout with targeted suppression cleanup via refactors. - Tightened OpenCode/GitHub review and release-marketing workflows.
- Updated AGENTS/tooling guidance and stdlib maintenance documentation.
Runtime & Correctness
Runtime builtin breadth completed for benchmark matrix
Runtime/operator work filled missing paths and removed stale suppression-heavy patterns:
- missing builtin neg/slice function coverage added and benchmarked
- operator creator/refactor passes reduced
nolintusage in runtime funcs - printf formatter internals were split and covered with focused tests
Example reliability fix
A delayed-echo example synchronization bug was fixed by correcting wait-group count wiring.
Benchmarks & Measurement
This release significantly expands reproducible benchmark slices for runtime behavior:
- foundation runtime e2e baseline slice
- support-wired atomic fan in/out coverage
- startup noop and atomic builtin operator batches
- scalar cast, routing/type, else/error/gate, and simple operator baselines
These changes improve visibility into runtime performance trends without introducing new language syntax.
CI, Lint, and Release Operations
- lint workflow naming/config alignment and stricter phase-1 profile enforcement
- contextual error propagation improvements in tooling paths
- release automation updates for Telegram and Discord announcement flows
- OpenCode PR-review policy tightened to focus on required changes
Docs & Harness Guidance
- hierarchical AGENTS harness and cross-tool rule shims added
- stdlib component coverage policy documented
- legacy
.agentlayout cleanup to keep harness guidance consistent
Language Surface
No language-level syntax or type-system semantic changes were introduced in this patch window.
📑 Related PRs
- #1112 typesystem: remove nolint suppressions via refactors
- #1111 runtime/funcs: remove nolint suppressions from operator creators
- #1110 chore(golangci): add phase-1 runtime funcs exclusions
- #1109 refactor: add contextual errors in tooling paths
- #1107 ci(lint): rename golangci check and set explicit config
- #1106 refactor(runtime): split printf formatter into focused helpers
- #1105 test(runtime): add coverage for printf template formatting
- #1103 chore: strict golangci profile with phase-1 suppression baseline
- #1102 opencode review: remove positive validation from AI PR comments
- #1095 chore(agent): clean up legacy .agent layout
- #1092 OpenCode PR review: only required changes, no praise
- #1091 Add Discord release news workflow
- #1090 benchmarks: add simple operator baseline slice
- #1089 examples: fix delayed echo wait group count
- #1087 ci: auto-run OpenCode review-pull-request skill on PR open
- #1086 runtime: add missing builtin neg/slice funcs and complete atomic builtin breadth
- #1085 benchmarks: add atomic builtin else/error and gate batch
- #1084 benchmarks: add atomic builtin routing/type benchmark batch
- #1083 benchmarks: add atomic scalar-cast builtin benchmarks
- #1082 docs: record stdlib coverage policy
- #1081 benchmarks: add atomic builtin float/string operator batch
- #1080 benchmarks: add startup noop and atomic builtin operator batch
- #1079 docs: add cross-tool rule shims
- #1078 benchmarks: add support-wired atomic fan in/out
- #1077 docs: adopt hierarchical AGENTS harness
- #1076 docs: tighten telegram release post skill format
- #1075 benchmarks: add atomic one-shot builtin batch
- #1074 ci: fix release telegram workflow for release events
- #1073 benchmarks: foundation runtime e2e baseline slice
Full Changelog: v0.36.0...v0.36.1
Post-release asset refresh (May 9, 2026)
Release binaries were re-uploaded from
maincommitf9dbb8e6to fix CLI-reported compiler version metadata (neva versionnow reports0.36.1). -
v0.36.1-0.20260422071121-df512ce2cae122 Apr 2026 pre-releaseNothing published for this version
-
v0.36.1-0.20260331115109-97857d59006531 Mar 2026 pre-releaseNothing published for this version
-
v0.36.031 Mar 2026Release notes
Open source →Engineered Stability
The previous "Pragmatic Power" release
v0.35focused on language and stdlib leverage.v0.36is about making that leverage safer and more repeatable in day-to-day work: stricter release builds, stronger quality gates, cleaner CI lanes, security/toolchain refresh, and reduced maintenance noise.🌟 Summary
- Security remediation pass completed across Go toolchain and dependencies.
- Repo toolchain moved to
go1.26.1(including CI). - Release build arguments were centralized and normalized for deterministic artifacts.
- CI pipeline now runs in explicit stages (
lint -> unit -> e2e) and uses shared e2e binary caching. - Local/CI quality gates are now explicit (
lint,test-unit,vulncheck,quality-gate,quality-gate-ci). - e2e/examples test lane returned to default Go package parallelism after hardening.
- NilAway cleanup landed across internal compiler packages.
- Release workflow guidance gained a compact repo-local skill with snippet quality checks.
- Published releases now have an automated Telegram announcement path.
- Stale lint suppressions were removed and
fieldalignmentcleanup was applied. - Agent guidance docs were consolidated into a compact router and updated with modern Go defaults.
🔒 Security & Toolchain
Vulnerability remediation
A dedicated sweep addressed reachable vulnerability findings and upgraded affected modules:
github.com/go-git/go-git/v5v5.11.0 -> v5.16.5github.com/cloudflare/circlv1.3.7 -> v1.6.3golang.org/x/cryptov0.21.0 -> v0.45.0golang.org/x/netv0.23.0 -> v0.47.0
go mod tidywas re-run to normalize the module graph after the update.Go toolchain update
Neva now targets:
go 1.26toolchain go1.26.1
CI workflows were aligned to the same version to keep local/CI behavior consistent.
📦 Release Build Discipline
Release build flags are now standardized in shared backend helpers and aligned with Make targets:
-trimpath-buildvcs=false-ldflags="-s -w"
This keeps end-user binaries compact and more reproducible across release paths (
install, native backend, wasm backend, and release builds).Release workflow support
Release operations were tightened further around lightweight repo-local guidance and post-publish automation:
- a compact
release-nevaskill now codifies the draft-first release flow and version-bump decision points - user-facing release snippets are expected to stay concise while still being valid Nevalang
- published releases can trigger Telegram announcement generation via OpenCode and shared messaging assets
⚙️ CI, E2E & Reliability
CI flow split + faster e2e bootstrap
The test workflow was restructured into ordered jobs:
lintunit_testse2e_tests
pkg/e2enow supports shared binary caching with safe fallback behavior, reducing repetitive rebuild work during e2e runs.Explicit quality gate
The repo now exposes a clearer local/CI quality path:
make lintmake test-unitmake vulncheckmake quality-gatemake quality-gate-ci
govulncheckalso runs as a dedicated workflow job, and optional Go-only hooks can mirror the same checks locally before commit.Parallelism rollout step
After introducing safer e2e/cache mechanics, the temporary explicit
-p 2cap for e2e/examples was removed in CI. The lane now relies on default Go package parallelism.Stdlib cache behavior clarified
Documentation/comments were tightened around stdlib cache invalidation:
- stdlib extraction remains content-based (correct for
embed.FSconstraints) - metadata-based fingerprinting remains limited to on-disk repo file use-cases
🧹 Code Health & Maintenance
- Removed stale
nolintsuppressions across the repo. - Applied struct field reordering where needed to satisfy
govetfield alignment checks. - Fixed NilAway findings in internal compiler packages and excluded test files from
make nilawayto keep the default developer path focused on production code. - AGENTS guidance was compacted into a high-signal docs router and extended with version-aware modern Go recommendations.
🧭 Language Surface
No language-level breaking changes were introduced in this release window. The focus of
v0.36is delivery quality and operational stability.📑 Related PRs
- #1072 ci: release marketing to Telegram via OpenCode
- #1071 Fix NilAway findings in internal code and exclude tests in Makefile
- #1070 Add explicit quality gate (lint/test/vulncheck) and remove vuln-scan skill
- #1069 skills: add compact release-neva skill and snippet quality checks
- #1068 docs: add modern Go guidance for agents
- #1066 ci(test): run e2e/examples with default Go package parallelism
- #1065 docs(cache): document stdlib fingerprinting constraints and close issue tails
- #1062 test(ci): split unit/e2e pipeline and cache e2e neva binary
- #1061 Fix vuln findings and add reusable vuln-scan skill
- #1060 docs(agents): condense AGENTS into compact router
- #1055 lint: remove stale nolint suppressions and enforce fieldalignment
- #1054 backend/golang: centralize release build args and reproducible flags
Full Changelog: v0.35.0...v0.36.0
-
v0.35.028 Feb 2026Release notes
Open source →Pragmatic Power
The previous "Back to Dataflow" release
v0.34has cleaned up the language surface and removed a lot of accidental complexity.Current "Pragmatic Power" release
v0.35is what comes next: making that simpler core actually pleasant and powerful in real programs. This release is more about real leverage.🌟 Summary
- New
bytesbuiltin data-type for effective IO operations. We no longer pretend that all bytes are strings. - Idiomatic type convertors in stdlib (
streams/dicts/strings/bytes). - Stdlib port naming was standardized (
data/res/err/sigdefaults) across many components to make APIs more predictable. - Even stricter syntax (nodes now must have explicit names in component definition).
- The
maybetype is no longer special case for type-system, it's justunionnow. - Removed deferred connections syntax and switched to explicit lock wiring.
- Array-bypass syntax was finalized as
[*](instead of=>), which is much clearer and less magical. - Neva LSP was moved to separate repository for maintainability.
- Core LSP language features landed (huge step for daily DX in editors).
- Fixed old issue with zombie processes after e2e by improving
pkg/e2epackage for end-to-end testing.
🧠 Language & Semantics
First-class
bytesbytesis now a first-class builtin type.Minimal snippet (nodes + network only):
read_all io.ReadAll? bytes_to_string strings.FromBytes println fmt.Println<any>? --- :start -> 'bytes_roundtrip.txt' -> read_all:filename -> bytes_to_string -> println -> :stopA concrete stdlib API example using
bytes:#extern(write_all) pub def WriteAll(filename string, data bytes) (res any, err error)Node (top-level) names are now required
It makes code more consistent and easier to reason about for LLMs.
// before (now invalid) import { fmt } def Main(start any) (stop any) { fmt.Println ... }// after import { fmt } def Main(start any) (stop any) { println fmt.Println ... }maybe/errormodeling cleanupmaybe<T>is now regular tagged-union modeling instd/builtin.pub type maybe<T> union { Some T None } pub type error struct { text string child maybe<error> }No special type-system path is needed for optional/error chaining.
Deferred connections removed
We finished the remaining language cleanup from
v0.34by removing deferred connection syntax.Before, you could write sugar like
a -> { b -> c }, where delivery frombtocwas deferred bya. It worked, but- It added one more connection form i.e. made language more complex
- It made dataflow less obvious (it's not clear that what's deferred is receiving by
cand not sending byb, which is clear using explicit locks - what desugarer was doing under the hood) - It made 1-1 mapping from source code to visual node editor impossible, which was the most critical problem among all 3. The best way to visualize deferred connection was to "desugar it" at the level of the visual editor, which means we would desugar it two times, at the different edges of the compilation spectrum, which... Doesn't feel right, let's say.
So now this is explicit wiring via
builtin.Lock:lock Lock<string> --- a -> lock:sig b -> lock:data lock -> cArray-bypass syntax finalized as
[*]Array bypass used to use
=>. Now it is explicit port-slot wildcard syntax on both sides:// before in:items => out:items // after in:items[*] -> out:items[*]This might seem like a opinionated change but actually it's just simplification we didn't see possible before - at AST level we used to have 2 kinds of connection, a normal one and array bypass one. Now array bypass is just a special case of normal connection where array slot index is
*(which is encoded as 255 - reserved uint8 value). So all connections are "normal" now. I.e. there are just "connections". Also[*]feels more consistent with[i](e.g.[0]) rather than using different kind of arrow=>.📦 Standard Library: Conversion Toolkit
Stdlib port naming standardization
A lot of stdlib APIs were normalized to follow port naming convention with (
data,res,err,sig) with boundary exceptions only when domain naming adds real value. The convention itself was finalized in thedocs/style_guide.mddocument.This is not a flashy feature, but it helps to form idiomatic conventions for the language and its standard library. This particular change should make it a little bit easier to reason about the port names. We expect you to just follow the convention without asking yourself a lot about "how do I name this port?". Also should help LLMs with codegen predictability.
New / improved conversion path components
streams.FromString(data string) (res stream<string>)streams.FromDict<T>(data dict<T>) (res stream<DictEntry<T>>)dicts.FromStream<T>(data stream<DictEntry<T>>) (res dict<T>)strings.FromBytes(data bytes) (res string)
This introduces idiomatic convention for data-type convertors. We have decided to continue follow "small core" philosophy and made type convertors simple components rather than language feature.
Example:
dict -> streamconst dict_value dict<string> = { a: 'one', b: 'two' } ... dict_to_stream streams.FromDict<string> for_each_println streams.ForEach<DictEntry<string>>{fmt.Println<any>}? wait streams.Wait --- :start -> $dict_value -> dict_to_stream -> for_each_println -> wait -> :stopExample:
stream -> dict(last write wins)const dict_entries list<DictEntry<string>> = [ { key: 'dup', value: 'one' }, { key: 'dup', value: 'forty-two' } ] ... list_to_stream streams.FromList<DictEntry<string>> stream_to_dict dicts.FromStream<string> println fmt.Println<any>? --- :start -> $dict_entries -> list_to_stream -> stream_to_dict -> println -> :stopScalar conversions
Builtin scalar converters now explicitly document intent (aligned with Go):
Int(float) -> int(truncate toward zero)Float(int) -> floatString(int) -> string(Unicode code point)
This gives a sane, predictable baseline while keeping non-total parsing/formatting in stdlib (
strconvstyle APIs).Bytes(string) -> bytesandString(bytes) -> stringinbuiltinare in progress.⚙️ Tooling & Architecture
Go 1.26 migration +
go fixdisciplineRepository now targets:
go 1.26toolchain go1.26.0
CI now enforces
go fix ./...cleanliness. If you haven't read about go fix then do it. It's awesome tool that automatically rewrites legacy Go code to its modern version respecting language and stdlib changes. Now every Neva release language is going to be better and better also because of this, among with many-many other reasons.LSP was moved + Refactoring
A lot of groundwork landed to make this split working:
- public
pkg/ast,pkg/core,pkg/indexer,pkg/typesystem, - in-repo
cmd/lspremoved, - canonical LSP implementation lives in
nevalang/neva-lsp.
This is important for velocity in
neva-lspandvscode-neva: compiler core stays focused, language tooling can evolve in its own repo.pkg/*APIs are now usable from external Go modulesExpose public APIs for external LSP extractionmeans you can now import Neva AST/typesystem packages directly from another Go module.Minimal example:
package main import ( "fmt" src "github.com/nevalang/neva/pkg/ast" ts "github.com/nevalang/neva/pkg/typesystem" ) func main() { var _ src.Component var _ ts.Expr fmt.Println("neva ast/typesystem imported successfully") }
LSP core language features (major milestone)
Core editor features landed:
textDocument/definition- jump to symbol definition.textDocument/references- find all usages.textDocument/rename(+ prepare rename) - safe symbol rename.textDocument/hover- quick symbol/type info.textDocument/documentSymbol- file outline navigation.textDocument/completion- entities, ports, and imports.textDocument/semanticTokens/full- syntax-aware highlighting.- CodeLens (
references,implementations) - inline code navigation counts.
This is the baseline for
vscode-nevaand future visual tooling over LSP transport.🧪 Reliability & Quality
- E2E infrastructure now handles timeout/cancel more safely by cleaning process groups to avoid orphan child processes.
- Additional lint debt on
mainwas cleaned while preparing this release baseline (staticcheck+wastedassignfindings). - Runtime JSON spacing corruption fix (
#1030) was a small but important bug-fix: pretty spacing no longer mutates string payload contents.
📑 Related PRs
Core to this release window:
- #1051 Switch builtin maybe/error to tagged unions
- #1049 fix(e2e): clean up orphan child processes on timeout/cancel
- #1039 chore: migrate repo to Go 1.26 and add gofix CI check
- #1038 Add streams.FromString and document converter policies
- #1036 Add first-class bytes type and migrate binary APIs
- #1035 Add dict<->stream converters in std
- #1034 Add Go-parity scalar converters for builtin and strconv
- #1031 Cleanup streams API and standardize stdlib port naming
- #1030 Fix runtime JSON spacing corruption in message formatting
- #1029 feat: require explicit aliases for top-level node declarations
- #1026 chore: remove cmd/lsp after extraction to neva-lsp
- #1025 Expose public APIs for external LSP extraction
- #1024 Move LSP indexer to pkg/indexer
- #1022 refactor: move ast and core packages to pkg
- #1020 LSP: add core language features
- #1018 refactor: remove deferred connections
- #1013 Replace array-bypass => with [*]
Full Changelog: v0.34.0...v0.35.0
- New
-
v0.34.1-0.20260224192518-3bbe2c437e0624 Feb 2026 pre-releaseNothing published for this version
-
v0.34.1-0.20260219170217-3675acc6f94719 Feb 2026 pre-releaseNothing published for this version
-
v0.34.1-0.20260218184039-db5adfde91f518 Feb 2026 pre-releaseNothing published for this version
-
v0.34.1-0.20260215181229-ec4b69fd3c2e15 Feb 2026 pre-releaseNothing published for this version
-
v0.34.1-0.20260215175933-a5dd3b11847615 Feb 2026 pre-releaseNothing published for this version
-
v0.34.1-0.20260202170526-6613dff1a16f02 Feb 2026 pre-releaseNothing published for this version
-
v0.34.029 Jan 2026Release notes
Open source →Back to Dataflow
🌟 Vision & Direction (Q1 2026)
This release is a turning point toward the 2026 Q1 priority: a polished, “wow‑factor” working prototype. To get there we needed to correct language design mistakes before moving forward. v0.34 finishes that simplification effort and brings Neva back to its roots: a small core and pure dataflow. We’re no longer trying to mimic conventional programming languages — we’re doubling down on what makes Neva different.
With this foundation in place, we can finally shift focus to the visual node editor. The language syntax/semantics are now kinda stable: expect small tweaks, but no major reshaping. The next frontier is stdlib APIs and patterns rather than the language itself.
This release continues the language simplification work: composite sender syntax is removed in favor of explicit stdlib components, and const/literal senders are now strictly chain-only. Alongside the language changes, you get a new
neva installcommand, clearer compiler diagnostics, and updated stdlib APIs.🧠 Language Changes
Why this simplification (context from #963)
Neva is a pure dataflow language: messages flow between nodes over connections. Composite senders (expressions, range syntax, ternary, switch syntax, union wrapping syntax) pull references from the network in sender position, which conflicts with chain-only semantics (constants/literals/union tags must be triggered). This created:
- Context-dependent rules (sometimes literals are allowed, sometimes not).
- Compiler↔stdlib coupling (syntax like
1..10impliesstreams.Rangeand auto-imports). - Visual/editor mismatch (phantom nodes/edges that don’t exist in the graph).
- Unsound or inconsistent typing for union elimination (see the
Switchnote below).
v0.34.0 removes these composite senders and requires explicit wiring. This makes the textual format a faithful serialization of the graph and restores a single, consistent rule: senders are nodes or chain-only literals/consts triggered by a signal.
Composite senders removed (breaking)
The following language-level constructs are removed in v0.34.0:
- Unary and binary operator expressions (e.g.,
-x,a + b,a && b). - Ternary operator.
switchlanguage construct.- Range syntax (
1..10). - Union senders (
Type::Tag(data)as a sender).
Use explicit stdlib components instead. This keeps the text format aligned with the visual dataflow model.
Before/After: Unary & Binary Operators
// before x + y -> out:data// after (builtin is implicit) add Add --- :x -> add:left :y -> add:right add -> :resBefore/After: Ternary
// before cond ? a : b -> out:data// after (builtin is implicit) ternary Ternary<string> --- :cond -> ternary:if :a -> ternary:then :b -> ternary:else ternary -> :resBefore/After:
switchconstruct// before value -> switch { case1 -> handle1 case2 -> handle2 _ -> handle_default }// after (builtin is implicit) switch Switch<string> --- :value -> switch:data :start -> [ 'Alice' -> switch:case[0] -> :out1, 'Bob' -> switch:case[1] -> :out2 ] switch:else -> :out_defaultBefore/After: Range
// before 1..10 -> stream:data// after import { streams } range streams.Range --- :start -> [ 1 -> range:from, 10 -> range:to ] range:res -> :stopBefore/After: Union senders
// before type MyUnion union { Tag int } MyUnion::Tag(value) -> handler// after (builtin is implicit) type MyUnion union { Tag int } union Union<MyUnion> --- :data -> union:data :start -> MyUnion::Tag -> union:tag union -> :resConst/literal senders must be chained (breaking)
Standalone const or literal senders are no longer allowed. They must appear in a chain triggered by a signal.
// before (invalid) $answer -> print:data 42 -> print:data // after :start -> [ $answer -> print:data, 42 -> print:data ]Switch<T>and theTypeplaceholder (type-system note)Removing the language
switchconstruct exposes a deeper type-system reality: union elimination is not expressible as a normal generic component. A true pattern match needs different output types per branch, but Neva’s type system assigns a single typeTtoSwitch<T>ports. A naiveSwitch<T>therefore cannot statically refine types by tag.To keep the language minimal and preserve switch-like behavior, Neva keeps
Switchas a stdlib component, while the compiler applies special typing rules to its case outputs. The signature uses a placeholder typeTypeto indicate “compiler-determined output type” per case:pub def Switch<T>(data T, [case] T) ([case] Type, else T)Typeis not a real runtime type. It is a documentation/typing placeholder that signals compiler participation. This is a deliberate, constrained “compiler magic” to keep the surface language small while acknowledging that union elimination is not soundly expressible as a normal generic function today (see #969 for details).Import blocks accept comments
Comments are now allowed inside
import { ... }blocks and as trailing comments on import lines.import { fmt strings // used for joining }Struct literals allow trailing commas
Multi-line struct literals can now end with a trailing comma.
const person Person = { name: 'Ada', }⚙️ Compiler & Tooling
neva installcommandBuild and install a Neva program to your Go bin path (
GOBIN,GOPATH/bin, or~/go/bin) using the package directory name as the binary name.neva install path/to/pkg
Real‑world examples:
# Install a CLI from a local module neva install ./cmd/hello # Install the main package from a module root neva install . # Then run it hello
Debug runtime validation (for language developers)
A new
--debug-runtime-validationflag is available for language developers. It emits a validation helper into the generated runtime to print unconnected senders/receivers for wiring inspection, without shipping that helper in the repo runtime by default.# Inspect runtime wiring during development neva run --debug-runtime-validation path/to/pkgDiagnostics improvements
- Unused inport errors now list the exact ports and use correct singular/plural grammar.
- Chained connection error locations now fall back correctly when the parser node has missing position metadata.
- Recursive unqualified component references are now a clear analyzer error with a hint to use
builtin.<Name>when appropriate.
📦 Standard Library
Dotenv loaders are signal-style (breaking)
std/os/dotenvloaders no longer return dictionaries. They load into the process environment and send a completion signal.import { os/dotenv } def Main(start any) (stop any) { load dotenv.Load --- :start -> load -> :stop }Load a specific file via
LoadFrom, and use the override variants when needed:import { os/dotenv } def Main(start any) (stop any) { load dotenv.LoadFrom --- :start -> './config/.env' -> load:data -> load:res -> :stop }import { os/dotenv } def Main(start any) (stop any) { load dotenv.LoadFromOverride --- :start -> './config/.env' -> load:data -> load:res -> :stop }Available components in
std/os/dotenv:LoadLoadFromLoadOverrideLoadFromOverride
New
os.EnvironRetrieve the current process environment as
list<string>inKEY=VALUEform. This mirrors Go’sos.Environ()API, which returns a slice ofKEY=VALUEstrings rather than a map, so Neva exposes the same shape for consistency with the runtime implementation.import { fmt os } def Main(start any) (stop any) { environ os.Environ println fmt.Println<list<string>> --- :start -> environ -> println -> :stop }streams.Rangeis now explicit (breaking)The
..syntax and sig-gatedRangevariant are removed. Usestreams.Rangewith explicit wiring.import { streams } def Main(start any) (stop any) { range streams.Range --- :start -> [ 1 -> range:from, 10 -> range:to ] range -> :stop }Union wrapping must be explicit (breaking)
Union senders are removed. Use the
Union<T>component.type MyUnion union { Tag int } def WrapUnion(start any, data int) (res MyUnion) { union Union<MyUnion> --- :data -> union:data :start -> MyUnion::Tag -> union:tag union -> :res }🔁 Migration Guide (Quick Map)
Unary/binary expressions -> builtin operators (e.g., Add, Sub, Eq) ternary -> Ternary<T> switch {...} -> Switch<T> 1..10 -> streams.Range (from/to wiring) Type::Tag(data) sender -> Union<T> Standalone literals/consts -> Chain from a signal Dotenv Load returning dict -> signal-only loaders + os.Environ📦 Stdlib Component Changes (Summary)
Added or changed components in v0.34.0:
os.Environ(new)os/dotenv.Load,LoadFrom,LoadOverride,LoadFromOverride(changed to signal-style)streams.Range(moved tostreams, single explicit variant)Union<T>(unchanged component; now required for union wrapping instead of union senders)
🧪 Testing & Quality
- Much stricter
golangci-lintconfiguration with an explicit allowlist and new quality/security linters enabled. Highlights includegosec,govetwithfieldalignment,depguard,gochecknoglobals,gochecknoinits,gocritic,revive,errorlint,nilerr/nilnil,copyloopvar, andtparallel. This tightened bar took focused cleanup work and materially improves correctness, security, and maintainability. - Examples and e2e fixtures updated for chained literals/consts.
- Beyond the removals, this release adds extensive tests, fixes long‑standing bugs, and refactors complex compiler/runtime paths. It’s been nearly two months of hard work since v0.33 (Dec 8), and we’re still on track for a “Neva release every month” cadence.
🧩 Misc Fixes & Refactors
- Stdlib extraction is now checksum-based. The embedded stdlib is hashed and compared against a
.checksumfile under~/neva/std. If it matches, the existing on-disk stdlib is reused; if it differs, the stdlib is fully re-extracted and the checksum updated. This prevents stale stdlib copies after upgrades while keeping fast startup when nothing changed. - Docs updated for new grammar and language simplification.
📑 Related Issues & PRs
Pull requests: #951, #953, #955, #956, #958, #974, #978, #981, #991, #992, #993, #994, #995, #997, #998, #1005, #1006, #1009
Full Changelog: v0.33.0...v0.34.0
-
v0.33.1-0.20251227090809-a320751d977a27 Dec 2025 pre-releaseNothing published for this version
-
v0.33.007 Dec 2025Nothing published for this version
-
v0.32.024 Oct 2025Nothing published for this version
-
v0.31.2-0.20250326163019-7adc3f1bb2d726 Mar 2025 pre-releaseNothing published for this version
-
v0.31.104 Mar 2025Nothing published for this version
-
v0.31.009 Feb 2025Nothing published for this version
-
v0.30.225 Jan 2025Nothing published for this version
-
v0.30.121 Jan 2025Nothing published for this version
-
v0.30.005 Jan 2025Nothing published for this version
-
v0.29.128 Dec 2024Nothing published for this version
-
v0.29.015 Dec 2024Nothing published for this version
-
v0.28.202 Dec 2024Nothing published for this version
-
v0.28.2-0.20241202203210-17893cea302002 Dec 2024 pre-releaseNothing published for this version
-
v0.28.129 Nov 2024Nothing published for this version
-
v0.28.1-0.20241129225201-094fcd058ace29 Nov 2024 pre-releaseNothing published for this version
-
v0.28.028 Nov 2024Nothing published for this version
-
v0.27.2-0.20241128172140-24a6710b619128 Nov 2024 pre-releaseNothing published for this version
-
v0.27.126 Nov 2024Nothing published for this version
-
v0.27.1-0.20241126182012-065edcf46edc26 Nov 2024 pre-releaseNothing published for this version
-
v0.27.1-0.20241125213011-9d300ee6ea9c25 Nov 2024 pre-releaseNothing published for this version
-
v0.27.1-0.20241124210709-e36e725b70fb24 Nov 2024 pre-releaseNothing published for this version
-
v0.27.1-0.20241122073254-9052e59a07c322 Nov 2024 pre-releaseNothing published for this version
-
v0.27.021 Nov 2024Nothing published for this version
-
v0.26.1-0.20241121215119-b121e64c16bc21 Nov 2024 pre-releaseNothing published for this version
-
v0.26.1-0.20241118194232-dffbf58a885d18 Nov 2024 pre-releaseNothing published for this version
-
v0.26.1-0.20241117213110-f7ae090bb74317 Nov 2024 pre-releaseNothing published for this version
-
v0.26.016 Nov 2024Nothing published for this version
-
v0.25.1-0.20241116121706-c9412b131cf916 Nov 2024 pre-releaseNothing published for this version
-
v0.25.1-0.20241102212639-05737abd250002 Nov 2024 pre-releaseNothing published for this version
-
v0.25.1-0.20241031201315-cb49430dddb931 Oct 2024 pre-releaseNothing published for this version
-
v0.25.1-0.20240714151849-4652071e153a14 Jul 2024 pre-releaseNothing published for this version
-
v0.25.001 Jul 2024Nothing published for this version
-
v0.24.1-0.20240701195859-a298081b984201 Jul 2024 pre-releaseNothing published for this version
-
v0.24.027 May 2024Nothing published for this version
-
v0.23.1-0.20240527214926-883a7ae7df6427 May 2024 pre-releaseNothing published for this version
-
v0.23.1-0.20240522122453-bb93b4be0c6222 May 2024 pre-releaseNothing published for this version
-
v0.23.1-0.20240520205145-0318dcd2a7d120 May 2024 pre-releaseNothing published for this version
-
v0.23.1-0.20240518172943-5fe456a453fc18 May 2024 pre-releaseNothing published for this version
-
v0.23.1-0.20240507185603-7696a9bb8dda07 May 2024 pre-releaseNothing published for this version