@neocompose/cli 0.70.5 → 0.71.1

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.70.5",
3
+ "version": "0.71.1",
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.70.5 -->
12
+ <!-- reviewed-through-cli: 0.71.1 -->
13
13
 
14
14
  # Neo Compose CLI
15
15
 
@@ -57,6 +57,11 @@ CLI 0.61 adds `while` and `do / while` loops, ordinal string `Replace`,
57
57
  ordered-list `Insert`, and method calls whose results may be discarded.
58
58
  See the [NeoScript reference](neoscript.md) for authoring syntax and limits.
59
59
 
60
+ CLI 0.71 adds collection queries, negative declaration patterns, and native
61
+ Debug output with authored stack traces. Compiled test caches include the
62
+ relative spec path because source coordinates are part of the compiled body.
63
+ Keep Debug output on stderr, including during JSON test runs.
64
+
60
65
  ## Shared implementation contract
61
66
 
62
67
  Manifest contracts, document comparison, normalization, and three-way merge
@@ -90,7 +95,10 @@ bases. A modified CLI can therefore write bad rows to a project its user may
90
95
  already write; keep preparation in shared `src/database` code rather than
91
96
  forking it in the CLI. The server still verifies a push's uploaded
92
97
  project-file bytes, and web editor commits use the shared client preparation protocol.
93
- Unrelated source files are not uploaded or recompiled on every push. A CLI lowering mismatch on a normal push is exposed by the next
98
+ Unrelated source files are not uploaded or recompiled on every push.
99
+ Optional source maps missing from valid stored bodies do not request a backfill.
100
+ Existing map changes still refresh locations on push; authored edits, dependency
101
+ changes, and explicit forced recompilation retain their normal compile scope. A CLI lowering mismatch on a normal push is exposed by the next
94
102
  canonical pull; `neo push --dry-run` remains the complete source-to-record
95
103
  rehearsal.
96
104
 
@@ -110,7 +118,7 @@ wrappers.
110
118
  The marker near the top of `SKILL.md` must exactly match the package version:
111
119
 
112
120
  ```html
113
- <!-- reviewed-through-cli: 0.70.5 -->
121
+ <!-- reviewed-through-cli: 0.71.1 -->
114
122
  ```
115
123
 
116
124
  The quoted version above is checked too, so this instruction cannot go stale
@@ -301,7 +301,9 @@ changed, skips codegen when only values changed since the last export into
301
301
  that Unity project, and writes `Library/NeoCompose/export.json` last for
302
302
  Unity to ingest.
303
303
 
304
- - A clean working copy exports the last pull. Local edits, `Files/` bytes
304
+ - A clean working copy exports the pulled head. Diagnostic location differences
305
+ alone, including line shifts after push inserts ids, do not make it local.
306
+ Local edits, `Files/` bytes
305
307
  included, make the export local: `project.json` gets
306
308
  `metadata.localExport`, Unity fails player builds and keeps saves under
307
309
  `NeoCompose/LocalExport`, and a push or a clean export ends it.
@@ -8,11 +8,12 @@ runtime ownership, evaluation, and migrations.
8
8
  - Inline bodies and snippets
9
9
  - Nullability and ownership
10
10
  - Numeric builtins
11
- - List builtins
11
+ - Collection builtins
12
12
  - Conditional and logical operators
13
13
  - Loops and transfer
14
14
  - Switch
15
15
  - Try/catch
16
+ - Debug output
16
17
  - Evaluation and migrations
17
18
 
18
19
  ## Inline bodies and snippets
@@ -187,12 +188,17 @@ every path that falls through matched the pattern, including when the guard's
187
188
  other paths return from a nested block:
188
189
 
189
190
  ```neo
190
- if (!(item is BedItem bedItem)) {
191
+ if (item is not BedItem bedItem) {
191
192
  throw "Expected a bed item";
192
193
  }
193
194
  return bedItem.Name;
194
195
  ```
195
196
 
197
+ `value is not SomeClass` negates a type test. An optional binding, as in
198
+ `value is not SomeClass item`, exists only where the test is known to be false:
199
+ the `else` branch, the right side of `||`, or after a rejecting guard. The
200
+ operand is evaluated once. `not` remains a normal identifier elsewhere.
201
+
196
202
  Use `SpriteInfo.Empty` when a required sprite should intentionally render no
197
203
  image. It is the canonical non-null empty sprite: it has no backing file and
198
204
  uses slice index zero.
@@ -252,6 +258,34 @@ materializing a filtered list. The same Count forms work on Dictionary and Set
252
258
  collections; dictionary predicates may accept `(key, value)` just like the
253
259
  other collection callbacks.
254
260
 
261
+ Use `Any()` or `Any((item) => predicate)` to check for a match, and
262
+ `All((item) => predicate)` to check every entry. Both short-circuit; an empty
263
+ collection has `Any() == false` and `All(...) == true`.
264
+
265
+ `Last`, `LastOrDefault`, `Single`, and `SingleOrDefault` accept zero arguments
266
+ or one predicate. `Last` throws when no entry matches. `Single` throws unless
267
+ exactly one matches; `SingleOrDefault` still throws for multiple matches.
268
+ The `OrDefault` forms return nullable entries and use `null` for no match.
269
+
270
+ Build eager, read-only list results with `SelectMany((item) => item.Children)`,
271
+ `OrderBy((item) => item.Name)`, `OrderByDescending((item) => item.Score)`,
272
+ `Skip(count)`, `Take(count)`, `SkipWhile((item) => predicate)`,
273
+ `TakeWhile((item) => predicate)`, `Reverse()`, and `Concat(other)`.
274
+ `SelectMany` requires a non-null list or set from its selector. Sorting is
275
+ stable, evaluates each key once, uses ordinal string comparison, and accepts
276
+ bool, int, float, decimal, or string keys, including nullable keys. Null sorts
277
+ first ascending and last descending. Negative skip/take counts
278
+ behave as zero. Reference entries keep their identity and storage permissions;
279
+ a read-only result does not grant additional write access to its entries.
280
+
281
+ ```neo
282
+ return this.Beds
283
+ .SelectMany((bed) => bed.Plants)
284
+ .Where((plant) => plant.Ready)
285
+ .OrderBy((plant) => plant.Name)
286
+ .Take(10);
287
+ ```
288
+
255
289
  Use `items.IndexOf(value)` to return the zero-based index of the first equal
256
290
  list entry, or `-1` when the value is absent. `IndexOf` is list-only and uses
257
291
  the same equality as `Contains`.
@@ -414,6 +448,26 @@ Do not use typed exception classes, parameterless catch, `finally`, `using`,
414
448
  patterns, or host-exception recovery. Completed writes before an error are not
415
449
  rolled back.
416
450
 
451
+ ## Debug output
452
+
453
+ Use `Debug.Log(message)`, `Debug.LogWarning(message)`, and
454
+ `Debug.LogError(message)` as void statements. `Debug.Assert(condition, message)`
455
+ logs an assertion failure when its non-null bool condition is false. Errors
456
+ and failed assertions log without throwing. Both assertion arguments are
457
+ evaluated once even when the condition passes; disabling a host sink also
458
+ preserves argument evaluation.
459
+
460
+ ```neo
461
+ Debug.Log($"Loaded {this.Items.Count} items");
462
+ Debug.Assert(this.Items.Any(), "Expected at least one item");
463
+ ```
464
+
465
+ Messages include authored NeoScript line/column locations and stack frames
466
+ when source metadata is available. Browser consoles and Unity use the matching
467
+ severity; CLI logs go to stderr so JSON stdout stays machine-readable. Getter
468
+ re-evaluation may emit the same log again. `Debug` is a builtin qualifier,
469
+ not a type; an authored local or Class named `Debug` takes precedence.
470
+
417
471
  ## Evaluation and migrations
418
472
 
419
473
  `neo script eval` uses authored values and the same evaluator as the web app.