@neocompose/cli 0.76.0 → 0.76.2

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.76.0",
3
+ "version": "0.76.2",
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.76.0 -->
12
+ <!-- reviewed-through-cli: 0.76.2 -->
13
13
 
14
14
  # Neo Compose CLI
15
15
 
@@ -68,7 +68,8 @@ opaque JSON or guessed syntax.
68
68
  its old parent no longer declares it. See the identity reference for limits.
69
69
  - Omit `@id` on new ordinary declarations and nested rows unless a same-push
70
70
  structural reference genuinely requires an explicit UUID. A successful push
71
- assigns the durable IDs and rewrites source.
71
+ assigns the durable IDs and inserts them into the authored source. Files that
72
+ get no new IDs keep their bytes.
72
73
  - Do not add a second `@id` to a root or static member initializer. The member
73
74
  ID owns that stored binding. Existing nested class/list rows retain their
74
75
  inline IDs; new rows normally omit them until push.
@@ -309,7 +310,9 @@ or server verification is involved.
309
310
  The CLI and VS Code extension share NeoScript formatting and read `.editorconfig`
310
311
  for `.neo` and `.neoflow` files. Set `indent_style`, `indent_size`, `end_of_line`,
311
312
  and `insert_final_newline` there to keep regenerated source consistent with your
312
- editor. Defaults are two spaces, LF, and a final newline. Push preserves authored
313
+ editor. Defaults are two spaces, LF, and a final newline. A NeoFlow prose
314
+ block's content and closing `"""` lines follow its opening `"""`, so re-indenting
315
+ never changes the text. Push preserves authored
313
316
  text when regeneration has the same tokens; pull preserves semantically unchanged
314
317
  files. Formatting-only body or source-location changes do not create a subsequent
315
318
  push, including stored initializer recipes, computed member defaults, and inline
@@ -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.76.0 -->
132
+ <!-- reviewed-through-cli: 0.76.2 -->
133
133
  ```
134
134
 
135
135
  The quoted version above is checked too, so this instruction cannot go stale
@@ -184,6 +184,12 @@ Readonly is shallow. A readonly collection's membership is fixed, while its
184
184
  entries' members follow their own storage and mutability. User class members
185
185
  still declare no storage.
186
186
 
187
+ A readonly member declared as a literal (no initializer or constructor call)
188
+ that reads neither `this` nor a constructor argument and holds nothing
189
+ writable is a constant. Instances share its declared value and store nothing
190
+ until a constructor or initializer block writes it. A readonly collection or
191
+ initializer is still built per instance.
192
+
187
193
  `@index(member: Field, kind: .Unique)` and
188
194
  `@column(member: Field, width: ..., visibility: ..., pin: ..., overflow: ...)`
189
195
  are repeatable List annotations. `member:` is a bare field name on the entry
@@ -269,10 +275,15 @@ Operator expressions are valid member defaults and store as computed
269
275
  initializers, the same way calls do — `public float Derived =
270
276
  Flags.Start / Flags.Scale;` is fine. Positions that store no rows still
271
277
  require literals: dictionary keys must be string literals or enum option
272
- literals for enum-keyed dictionaries, and Vector/Color components must be numeric
273
- literals. When a computed list or dictionary entry
274
- carries an authored `@id`, parenthesize the expression — `@id("row")
275
- (A.B / A.C)` — so the annotation names the row rather than its left operand.
278
+ literals for enum-keyed dictionaries, and Color components must be numeric
279
+ literals. In a static member or its collection entries, a vector with a
280
+ computed component, such as `new Vector2(Probe.X, 1)`, stores as a computed
281
+ initializer. Instance member defaults, including their collection entries,
282
+ still require numeric literal vector components. When a computed list or
283
+ dictionary entry carries an authored `@id`, parenthesize the expression —
284
+ `@id("row") (A.B / A.C)` — so the annotation names the row rather than its left
285
+ operand.
286
+ A push that assigns such a row's ID adds those parentheses itself.
276
287
 
277
288
  Numeric literals do not use C# suffixes: write `0` or `0.5`, not `0f` or
278
289
  `0.5f`. The declared/contextual type determines whether a literal is stored as
@@ -459,12 +470,13 @@ construction remain subject to storage and `readonly` restrictions.
459
470
  Runtime construction never supplies an Immutable member: an initializer block,
460
471
  constructor body, base-clause argument, or generated C# factory cannot set one.
461
472
  The value is never stored with the instance. When the declaration, including
462
- every row it owns, reads neither `this` nor a constructor argument, the member
463
- is a constant and every instance shares one value. Otherwise each instance
464
- evaluates the declared initializer with its own `this` and constructor
465
- arguments, again after a reload. A method group such as `selector: SelectTorso`
466
- binds `this`. `Clone()` shares an authored or constant Immutable value and
467
- re-evaluates a per-instance one. A class with a required Immutable member and
473
+ every row it owns, reads neither `this` nor a constructor argument, and no
474
+ value of its type holds a writable member, the member is a constant and every
475
+ instance shares one value. Otherwise each instance evaluates the declared
476
+ initializer with its own `this` and constructor arguments, again after a
477
+ reload. A method group such as `selector: SelectTorso` binds `this`.
478
+ `Clone()` shares an authored Immutable value or a constant and re-evaluates a
479
+ per-instance one. A class with a required Immutable member and
468
480
  no initializer cannot be constructed at runtime; only authored values construct
469
481
  it.
470
482
 
@@ -55,12 +55,10 @@ such as `set(int value) => this.Raw = value;`. An expression whose value would
55
55
  simply be discarded is rejected with a diagnostic that names the block body as
56
56
  the fix.
57
57
 
58
- `neo push` and `neo pull` canonicalize a stored body to the shorthand when its
59
- authored spelling is exactly one `return` statement that fits on one line;
60
- anything else re-emits as a block. Setters always re-emit as blocks. A push
61
- preserves the form you authored for members it did not otherwise rewrite, so
62
- choosing longhand for a one-line getter is stable; a fresh `neo pull` writes
63
- the canonical shorthand.
58
+ `neo pull` and canonical emission write a body as the shorthand when it is
59
+ exactly one `return` statement that fits on one line, and anything else as a
60
+ block. Setters are always blocks. `neo push` keeps the body form you authored,
61
+ so choosing longhand for a one-line getter is stable.
64
62
 
65
63
  Properties require a getter implementation. A bodyless `{ get; }` contract
66
64
  requires `abstract` on the member, even inside an abstract class, for example
@@ -122,11 +120,14 @@ class and derived classes may invoke it or call `Clear()`; public external
122
120
  callers may subscribe and unsubscribe with `+=` and `-=` but cannot raise or
123
121
  reset the action.
124
122
 
125
- Inline `NeoDelegate` lambdas may be returned or stored and may read surrounding
126
- locals and parameters. Those values are captured when the lambda is created,
127
- so later changes to the outer binding do not alter the closure. Explicit lambda
128
- parameter annotations accept the same type grammar as declarations, including
129
- `decimal`, generic parameters, collections, arrays, and nullable types.
123
+ Inline `NeoDelegate` lambdas may be returned, stored, or assigned to a typed
124
+ local such as `NeoDelegate<int, int> twice = (x) => x * 2;`, and may read
125
+ surrounding locals and parameters. Those values are captured when the lambda is
126
+ created, so later changes to the outer binding do not alter the closure.
127
+ Typed locals also accept generic class types such as `Box<int> box = new(1);`.
128
+ Explicit lambda parameter annotations accept the same type grammar as
129
+ declarations, including `decimal`, generic parameters, collections, arrays, and
130
+ nullable types.
130
131
 
131
132
  A lambda may use an expression body too: `(x) => x * 2` is the block body
132
133
  `(x) => { return x * 2; }`. In a void delegate the expression is a statement,
@@ -549,7 +550,7 @@ locally, like push. If another commit lands while it runs, the run is refused:
549
550
  run it again. `neo loc` writes work the same way: a write refused because
550
551
  another commit landed is run again.
551
552
 
552
- VS Code rename follows override families and class constructors, resolves contextual enum options such as `.Success`, and keeps local-variable renames scoped to their declaration. Assigned IDs are not required for these refactorings.
553
+ VS Code rename follows override families and class constructors, resolves contextual enum options such as `.Success`, renames a constructor parameter's named arguments (`new Item(count: 1)`) in bodies, initializers, specs, and base clauses, and keeps local-variable renames scoped to their declaration. Assigned IDs are not required for these refactorings.
553
554
 
554
555
  ## Member change listeners
555
556