@neocompose/cli 0.77.0 → 0.78.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neocompose/cli",
3
- "version": "0.77.0",
3
+ "version": "0.78.0",
4
4
  "description": "Neo Compose native project-source CLI with bidirectional sync.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -9,7 +9,7 @@ description: >-
9
9
  `@neocompose/cli` or `node cli/bin/neo.mjs` in the neo-compose repository.
10
10
  ---
11
11
 
12
- <!-- reviewed-through-cli: 0.77.0 -->
12
+ <!-- reviewed-through-cli: 0.78.0 -->
13
13
 
14
14
  # Neo Compose CLI
15
15
 
@@ -129,7 +129,7 @@ wrappers.
129
129
  The marker near the top of `SKILL.md` must exactly match the package version:
130
130
 
131
131
  ```html
132
- <!-- reviewed-through-cli: 0.77.0 -->
132
+ <!-- reviewed-through-cli: 0.78.0 -->
133
133
  ```
134
134
 
135
135
  The quoted version above is checked too, so this instruction cannot go stale
@@ -91,7 +91,7 @@ Use context-aware typed annotations:
91
91
  - `@visibility(.Hidden)` only on a class; absence means visible.
92
92
  - Stateful settings use contextual enum cases, such as
93
93
  `@settings(format: .Plain)` and `@settings(kind: .Unordered)`.
94
- - `@settings(...)` before a `List` element or `Dictionary` value type
94
+ - `@settings(...)` before a `List` or `Set` element or `Dictionary` value type
95
95
  configures the collection's entries: `List<@settings(format: .Plain) string>`,
96
96
  `Dictionary<string, @settings(min: 0) int>`. Only the member that declares
97
97
  the collection spells them; overrides share its entries.
@@ -213,6 +213,19 @@ An explicit construction must be assignable to its receiving type. For example,
213
213
  `List<Base>` accepts `new Derived()` when `Derived` inherits `Base`, but rejects
214
214
  an unrelated class at `new`. Generic arguments must also be compatible.
215
215
 
216
+ A generic class without a declared constructor is constructed with its type
217
+ arguments, such as `new Box<int> { Item = 4 }` or a target-typed
218
+ `new() { Item = 4 }`. A `T` field is required unless the type argument is
219
+ nullable, so `new Box<int?>()` may omit it. `new Box()` is rejected as an open
220
+ generic Class. Inside the class, methods and field initializers construct with
221
+ the class's own parameter, such as `public Bag<T> B = new Bag<T>();`. Such an
222
+ initializer with fields or entries, like `new Bag<T> { N = 3 }`, runs per
223
+ instance, since each instance closes `T` differently. A type
224
+ argument that wraps the parameter, such as `new Bag<List<T>>()`, is rejected.
225
+ Type arguments must satisfy `extends` constraints in bodies too.
226
+ A type argument may be a delegate, such as `Box<NeoDelegate<int, int>>`, but
227
+ not a `NeoAction`, which is never a value.
228
+
216
229
  Primary-constructor parameters can initialize generic collection fields directly:
217
230
 
218
231
  ```neo
@@ -221,7 +234,8 @@ class Box<T>(List<T> value) {
221
234
  }
222
235
  ```
223
236
 
224
- The same rule applies to `Dictionary<string, T>` and nested collections.
237
+ The same rule applies to `Dictionary<string, T>`, nested collections, and
238
+ stored instances such as `public static Box<int> Value = new([1, 2]);`.
225
239
 
226
240
  ## Member and relation rules
227
241
 
@@ -257,6 +271,36 @@ A `Reference<T>` member satisfies an interface `T Foo { get; }` or
257
271
 
258
272
  Constructor and function parameters use `Set<T>` for several selections.
259
273
 
274
+ ### Set members
275
+
276
+ `Set<T>` is an insertion-ordered collection that can't hold duplicates. The
277
+ element picks the storage:
278
+
279
+ - An enum `Set<Trait>` is a multi-select Enum.
280
+ - `Set<Reference<T>>` is a multi-select lookup.
281
+ - `Set<NeoDialogueReference>` is a multi-select dialogue lookup.
282
+ - Any other element makes an owned Set whose entries are rows, like a List.
283
+
284
+ An owned Set holds `bool`, `int`, `float`, `decimal`,
285
+ `@settings(format: .Plain) string`, vectors, `Color`, sprites, audio clips,
286
+ or a class. Elements can't be nullable, collections, variants, delegates,
287
+ actions, or interfaces. A class entry is unique by row, a value entry by its
288
+ value. `@index` and `@column` work as on a List; `kind:` is an error, since a
289
+ Set is always insertion-ordered.
290
+
291
+ ```neo
292
+ @index(member: Slug, kind: .Unique)
293
+ public Set<Quest> ActiveQuests = [];
294
+ public Set<int> LuckyNumbers = [3, 7];
295
+ public Set<Trait> Traits = [.Brave];
296
+ ```
297
+
298
+ `selection:` is an error everywhere: `Set<T>` selects many and `T` selects
299
+ one. The language server's quick fix rewrites `@settings(selection: .Multi)`
300
+ to a `Set<…>` type. A default literal that repeats a value fails `push`, and a
301
+ `List<Trait>` stays an ordered List of enum values. Queries over a Set, such
302
+ as `Where` and `OrderBy`, return a Set; `ToSet()` turns a List into one.
303
+
260
304
  Declare a multicast event as `NeoAction<…>`. Its value is an ordered listener
261
305
  set, so give it a bracketed list of method groups — never a lambda, and never
262
306
  a bare method group — and never mark it `required`: the rest state is the
@@ -410,7 +454,12 @@ class Foo(string bar, bool isFun) {
410
454
  Foo value = new(bar: "BAR", isFun: true) { IsFun = false };
411
455
  ```
412
456
 
413
- Header parameters are in scope throughout the class. Permit at most one `init`
457
+ Header parameters are in scope throughout the instance members of the class.
458
+ Field initializers, collection entries, object initializers, and lambdas read
459
+ them per construction, so `public NeoDelegate<int> Value = () => n;` returns
460
+ each instance's own `n`. A lambda can also read `this`, as in
461
+ `() => n + this.M`; the rest of an initializer can't. Static members have no
462
+ construction and can't read header parameters. Permit at most one `init`
414
463
  block. A header constructor disables implicit parameterless `new` and forbids
415
464
  additional constructor overloads. Its derived constructor identity is not
416
465
  authored with `@id`.
@@ -137,6 +137,15 @@ Other static fields can call them in their initializers, as in
137
137
  `public static int First = Helper.Run();`. Outside a lambda body, a field
138
138
  initializer qualifies the members it reads; a bare `Run()` or `Number` there is
139
139
  an unknown name.
140
+ A delegate field default is the exception: it may name a method group bare.
141
+ `Value = Read` or `this.Read` binds each new instance to its own `Read`, and a
142
+ static function may be named as `Read` or qualified as `Holder.Read`/`Other.Read`.
143
+ A qualified method group must name a static function. Method groups use the same
144
+ signature rule as in a body, and a mismatch is reported at the declaration.
145
+ A static field that names another static copies a value, as in
146
+ `public static int B = Holder.A;`; a class, List, or Dictionary static shares
147
+ the same object. A static delegate cannot copy another Class's delegate field,
148
+ because its closure compiles in its own Class; wrap it as `() => Other.Call()`.
140
149
  Collection type arguments in constructions, such as `new Box<List<int>>([1, 2])`,
141
150
  work even when no field declares that collection type. Preparation includes the
142
151
  needed type descriptors; spec-only types remain in the test candidate.
@@ -312,6 +312,11 @@ different. The name must end with the binary's extension, because pull
312
312
  rebuilds the file's path from it. With no template annotation, the CLI persists the complete built-in
313
313
  Unity defaults for the file kind.
314
314
 
315
+ Template-backed Unity settings may contain sparse nested override values and leaf
316
+ paths such as `platformSettings.standalone.maxTextureSize` or
317
+ `spriteSettings.pivot.x`. Preserve these paths during synchronization so untouched
318
+ settings continue inheriting from the template.
319
+
315
320
  A top-level `NeoImage` or `NeoAudioClip` declaration in any definition file
316
321
  can stand in for an inline entry. The registry lists it by name
317
322
  (`NeoAudioClip SwordHit = SWORD_HIT;`), and the declaration carries the `@id`,