@neocompose/cli 0.61.4 → 0.61.5

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,9 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.61.5] - 2026-10-01
4
+
5
+ - Report concrete properties without getter bodies at their source file, line, and member name before manifest lowering. The shared VSCode diagnostic explains how to implement the getter, declare an abstract contract, or use a stored field.
6
+
3
7
  ## [0.61.4] - 2026-10-01
4
8
 
5
9
  - Narrow implicit instance members after null and type checks just like their `this.Member` spelling, including nested conditions, assignments, and loop invalidation.
package/dist/neo.mjs CHANGED
@@ -27723,6 +27723,15 @@ function validateClassMemberModifiers(ref, environment, diagnostics) {
27723
27723
  related(ref.location, "The containing class is declared here.")
27724
27724
  );
27725
27725
  }
27726
+ if (member.kind === "property" && !modifiers.has("abstract") && findProjectSourceAccessorBody(member.body.text, "get") === null) {
27727
+ diagnose(
27728
+ diagnostics,
27729
+ ref.uri,
27730
+ member.nameRange,
27731
+ "concrete-property-getter-body",
27732
+ `Property '${ref.declaration.name}.${member.name}' requires a getter body. Implement 'get { return ...; }' or 'get => ...;', declare the property abstract in an abstract class, or use a field with an initializer for stored data.`
27733
+ );
27734
+ }
27726
27735
  if (modifiers.has("abstract") && member.kind === "field" && member.initializer) {
27727
27736
  diagnose(
27728
27737
  diagnostics,
@@ -28318,6 +28327,7 @@ var init_project_source_type_checker = __esm({
28318
28327
  "use strict";
28319
28328
  init_language_spec();
28320
28329
  init_project_source_ast();
28330
+ init_project_source_accessors();
28321
28331
  init_project_source_identifiers();
28322
28332
  BUILTIN_ARITY = /* @__PURE__ */ new Map([
28323
28333
  ["List", 1],
@@ -134246,7 +134256,7 @@ var init_project_document_cache = __esm({
134246
134256
  init_src();
134247
134257
  init_project_documents();
134248
134258
  PROJECT_SOURCE_BUILD_CACHE_PATH = ".neo/build/project-source-analysis-v4.json";
134249
- PROJECT_SOURCE_BUILD_CACHE_REVISION = 2;
134259
+ PROJECT_SOURCE_BUILD_CACHE_REVISION = 3;
134250
134260
  }
134251
134261
  });
134252
134262
 
@@ -146399,7 +146409,7 @@ var init_registry2 = __esm({
146399
146409
  "../packages/manifest/schema-contract/registry.mjs"() {
146400
146410
  "use strict";
146401
146411
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
146402
- cliVersion: "0.61.4",
146412
+ cliVersion: "0.61.5",
146403
146413
  projectFileUploadBatchSize: 32,
146404
146414
  documentRecords: {
146405
146415
  member: {
@@ -155079,7 +155089,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
155079
155089
  async function main() {
155080
155090
  const args = parseArgs(process.argv.slice(2));
155081
155091
  if (args.command === "--version") {
155082
- console.log("0.61.4");
155092
+ console.log("0.61.5");
155083
155093
  return;
155084
155094
  }
155085
155095
  if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neocompose/cli",
3
- "version": "0.61.4",
3
+ "version": "0.61.5",
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.61.4 -->
12
+ <!-- reviewed-through-cli: 0.61.5 -->
13
13
 
14
14
  # Neo Compose CLI
15
15
 
@@ -110,7 +110,7 @@ wrappers.
110
110
  The marker near the top of `SKILL.md` must exactly match the package version:
111
111
 
112
112
  ```html
113
- <!-- reviewed-through-cli: 0.61.4 -->
113
+ <!-- reviewed-through-cli: 0.61.5 -->
114
114
  ```
115
115
 
116
116
  The quoted version above is checked too, so this instruction cannot go stale
@@ -60,6 +60,12 @@ preserves the form you authored for members it did not otherwise rewrite, so
60
60
  choosing longhand for a one-line getter is stable; a fresh `neo pull` writes
61
61
  the canonical shorthand.
62
62
 
63
+ Properties require a getter implementation. A bodyless `{ get; }` contract
64
+ requires `abstract` on the member, even inside an abstract class, for example
65
+ `public abstract int Count { get; }`. For stored data, declare a field such as
66
+ `public int Count = 0;`. VSCode and the CLI diagnose a missing getter body at
67
+ the property name. Interface property contracts remain bodyless.
68
+
63
69
  Declare a bodyless NeoScript contract with `abstract`, for example
64
70
  `public abstract bool Equals(Item other);`. Reserve `native` for host-provided
65
71
  functions; concrete NeoScript overrides inherit the abstract signature.