@neocompose/cli 0.67.4 → 0.68.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.68.0] - 2026-10-04
4
+
5
+ - Author member subscriptions with `value.Field.OnChanged += handler` and `-=`, and persist wiring with `@listeners(Field: [handler])`. Listener arguments must be named; multiple fields may appear in any order.
6
+ - Pull and push preserve listeners on virtual defaults without creating value overrides. Positional patches remain the primary source form.
7
+ - Complete and validate listener field names and handler types in NeoScript editors. Dialogue dry-runs validate wiring with gameplay dispatch disabled.
8
+ - Export schema 35 requires the matching SDK 0.57.0. Compiler revision 17 remains unchanged because existing IR is compatible.
9
+ - A bare call to a void method, such as `Finish(.Success);`, compiles as a statement like `this.Finish(.Success);`. Before, it failed with "returns void and cannot be used as a value" ([#1178](https://github.com/ryanbliss/neo-compose/issues/1178)).
10
+ - A method parameter can be named `value`, as in `protected virtual T Apply(T value) => value;`. Only property setters bind an implicit `value`. Before, push and status failed with document-shape and animation-validation errors that never named the parameter ([#1181](https://github.com/ryanbliss/neo-compose/issues/1181)).
11
+ - A base constructor call can omit parameters that have defaults, as in `: ValueWatcher<int>(initial: initial)` when `skip` defaults to `false`. Base calls resolve by argument names, with defaults filling the rest, and the fewest defaults wins. Lowering stores each name spelled as the chosen base constructor declares it. Status reports a base call that push would reject where it is written: a mismatched or ambiguous call, a positional argument to an overloaded base, arguments to a base with no constructors or to no base, and an empty or missing call when no base constructor is parameterless. Base arguments that differ only in case are duplicates, as are two arguments that bind one parameter when either is positional. Before, push failed with "matches none of its constructors" at `<initializer-materialization>:1:1` ([#1182](https://github.com/ryanbliss/neo-compose/issues/1182)).
12
+ - A class member default can name a local value, either directly or as an entry of an ordered or nested list, as in `public Quests Quests = new() { Core = [HardAsStoneQuest] };`. The default lowers as if the local's expression were written inline. Write-back keeps the bare name wherever it was written, including a field local equal to the field's default, and an entry local keeps its `@id`. `@listeners` written below the root of a local that a default or static names whole stays in the local. Status reports, at the annotation, wiring on that local's root (write it on the name) and wiring inside a local used as a list entry or field (write it at the use, or write the local's expression inline there to wire values inside it). An entry of a direct unordered list default still can't be a local, and status reports this at the member. A default or static the server sets to `null` pulls as `null` at the member instead of failing the pull with a `null` local. Before, a row-backed local failed push with "requires new(...)", and write-back inlined the local's settled expression into the class file ([#1176](https://github.com/ryanbliss/neo-compose/issues/1176), [#1179](https://github.com/ryanbliss/neo-compose/issues/1179)).
13
+ - Status and push report a stored value that would keep a closure with captured values, as in `new Holder(1) { Apply = Clamps.Clamp(0, 4) }` in `Root.neo` when `Clamp` returns a lambda that reads its `min` and `max` parameters. The server compiles a stored closure from its source, which drops the values it captured, so the error sits on the construction, gives the path to the closure (member, list entry, unordered entry, or constructor argument), and quotes it. This applies to member slots, statics, and values with an `@id`. Closures that capture nothing store as before, and a class member default still creates capturing closures at runtime. A delegate slot or static can be set from a call that returns a closure, as in `Apply = Clamps.Increment()`, and stores the closure it returns; before, status and push failed with "Delegate method groups require a function, NSFunction, or NSDelegate member on the current Class." Before, a capturing closure failed push in preparation with "Unknown identifier 'min'" and a value id ([#1180](https://github.com/ryanbliss/neo-compose/issues/1180)).
14
+
3
15
  ## [0.67.4] - 2026-10-04
4
16
 
5
17
  - Removing an entry from an object initializer is a change. Push deletes that override and the member reads its default again. Previously, on instances stored without a recorded construction, like the `new NeoSpriteObject { Sprite = ... }` in a `Children` list, `neo status` said the working copy was clean and the next pull wrote the entry back.