@neocompose/cli 0.73.0 → 0.73.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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.73.2] - 2026-10-08
4
+
5
+ - Use the same pending getter identity in schema declarations and NeoFlow interpolation. New getters export before their first push, including inherited getters, without manually authored IDs.
6
+
7
+ - Reject lookup declarations and constructed targets incompatible with their configured collection before push, test, or export. Preserve valid subclass lookups and report declaration errors at the authored collection annotation.
8
+
9
+ ## [0.73.1] - 2026-10-08
10
+
11
+ - Breaking: rename `PriorityOption` to `NeoPriorityOption` in priority groups, to match `NeoPriorityGroup`. The old name is a compile error that names its replacement, and dialogue priorities that use the option still resolve. Stored data doesn't change. `neo pull` writes the new name.
12
+
3
13
  ## [0.73.0] - 2026-10-08
4
14
 
5
15
  - Trigger dialogues from NeoScript. `root.Dialogues` mirrors the generated C# `Dialogues`, with `TryTrigger(dialogueId, onFinish)`, `CanTrigger(dialogueId)`, `VisitCount`, and `HasVisited`. Standard groups get `TryTrigger(onFinish)` and `CanTrigger()`, lookup groups take their entry class, and `NeoDialogueReference` gets `TryTrigger(onFinish)` and `CanTrigger()`. `TryTrigger` compiles only in functions and dialogue actions. `neo test`, `neo script eval`, and dialogue dry runs return false.
package/dist/neo.mjs CHANGED
@@ -1202,7 +1202,8 @@ var init_dialogue_types = __esm({
1202
1202
  { base: "NeoDialogueReference", value: "NeoDialogueReference" }
1203
1203
  ],
1204
1204
  ["DialogueGroup", { base: "NeoDialogueGroup", value: "NeoDialogueGroup" }],
1205
- ["PriorityGroup", { base: "NeoPriorityGroup", value: "NeoPriorityGroup" }]
1205
+ ["PriorityGroup", { base: "NeoPriorityGroup", value: "NeoPriorityGroup" }],
1206
+ ["PriorityOption", { base: "NeoPriorityOption", value: "NeoPriorityOption" }]
1206
1207
  ]);
1207
1208
  BOOL_TYPE = { kind: "primitive", name: "bool" };
1208
1209
  INT_TYPE = { kind: "primitive", name: "int" };
@@ -20691,6 +20692,13 @@ function span(identity2) {
20691
20692
  function materializedId(identity2, kind, name) {
20692
20693
  return materializedIdentityId(identity2, kind, name);
20693
20694
  }
20695
+ function materializedMemberId(owner, member) {
20696
+ return materializedId(
20697
+ member,
20698
+ owner.kind === "class" ? "member" : "interface-member",
20699
+ `${owner.name}.${member.name}`
20700
+ );
20701
+ }
20694
20702
  function materializedIdentityId(identity2, kind, name) {
20695
20703
  return identity2.id ?? `__pending__:${kind}:${encodeURIComponent(identity2.source.uri)}:${identity2.source.range.start.line}:${identity2.source.range.start.character}:${encodeURIComponent(name)}`;
20696
20704
  }
@@ -27192,6 +27200,7 @@ function sourceDialogueGroups(source) {
27192
27200
  if (cached) return cached;
27193
27201
  const symbols = /* @__PURE__ */ new Map();
27194
27202
  const globals = /* @__PURE__ */ new Map();
27203
+ const priorityGroups = /* @__PURE__ */ new Map();
27195
27204
  const options = /* @__PURE__ */ new Map();
27196
27205
  for (const symbol of source.symbols) {
27197
27206
  if (symbol.kind !== "global") continue;
@@ -27199,12 +27208,13 @@ function sourceDialogueGroups(source) {
27199
27208
  continue;
27200
27209
  const id2 = symbol.id ?? `${symbol.location.uri}#${symbol.name}`;
27201
27210
  globals.set(symbol.name, id2);
27211
+ if (symbol.detail === "NeoPriorityGroup")
27212
+ priorityGroups.set(symbol.name, id2);
27202
27213
  symbols.set(id2, symbol);
27203
27214
  }
27204
27215
  for (const symbol of source.symbols) {
27205
- if (symbol.kind !== "graphChild" || symbol.detail !== "PriorityOption")
27206
- continue;
27207
- const owner = globals.get(symbol.ownerName ?? "");
27216
+ if (symbol.kind !== "graphChild") continue;
27217
+ const owner = priorityGroups.get(symbol.ownerName ?? "");
27208
27218
  if (!owner) continue;
27209
27219
  const id2 = symbol.id ?? `${owner}.${symbol.name}`;
27210
27220
  symbols.set(id2, symbol);
@@ -27545,6 +27555,7 @@ function collectGlobalChildEntries(syntax, declaration) {
27545
27555
  const value = tokens[index + 3];
27546
27556
  entries.push({
27547
27557
  typeName: token.text,
27558
+ typeRange: token.range,
27548
27559
  name: name.text,
27549
27560
  nameRange: name.range,
27550
27561
  annotations: pendingAnnotations,
@@ -43880,6 +43891,16 @@ function validateAnnotations(uri, annotations, context, environment, diagnostics
43880
43891
  continue;
43881
43892
  }
43882
43893
  }
43894
+ if (annotation2.name === "settings" && field.name === "collection" && "type" in context) {
43895
+ validateLookupCollectionType(
43896
+ uri,
43897
+ argument2.text,
43898
+ argument2.range,
43899
+ context.type,
43900
+ environment,
43901
+ diagnostics
43902
+ );
43903
+ }
43883
43904
  validateExpressionText(
43884
43905
  uri,
43885
43906
  argument2.text,
@@ -43893,6 +43914,37 @@ function validateAnnotations(uri, annotations, context, environment, diagnostics
43893
43914
  }
43894
43915
  }
43895
43916
  }
43917
+ function validateLookupCollectionType(uri, collection, range2, declared, environment, diagnostics) {
43918
+ const path = collection.trim().split(".");
43919
+ const [owner, name] = path;
43920
+ if (path.length !== 2 || owner === void 0 || name === void 0) return;
43921
+ const field = sourceClassMemberForType({ name: owner }, name, environment);
43922
+ if (!field) return;
43923
+ const collectionType = substituteSemanticType(
43924
+ semanticType(field.member.type),
43925
+ field.bindings
43926
+ );
43927
+ const entryIndex = collectionElementIndex(collectionType.name);
43928
+ const entry = entryIndex === null ? void 0 : collectionType.arguments?.[entryIndex];
43929
+ const target = declared.name === "List" || declared.name === "Set" ? declared.arguments?.[0] : declared;
43930
+ if (!entry || !target) return;
43931
+ if (!environment.types.has(target.name) || !environment.types.has(entry.name))
43932
+ return;
43933
+ if (constructionTypesAssignable(
43934
+ { ...target, nullable: false },
43935
+ { ...entry, nullable: false },
43936
+ environment.globals,
43937
+ environment
43938
+ ))
43939
+ return;
43940
+ pushDiagnostic(
43941
+ diagnostics,
43942
+ uri,
43943
+ range2,
43944
+ "lookup-collection-type-mismatch",
43945
+ `Lookup declares ${describeType(target)}, but collection ${collection.trim()} holds ${describeType(entry)}.`
43946
+ );
43947
+ }
43896
43948
  function fieldsForAnnotation(name, context, environment) {
43897
43949
  if (name === "id") {
43898
43950
  return context.kind === "class" || context.kind === "schema" || context.kind === "member" || context.kind === "variantGlobal" || context.kind === "projectFile" || context.kind === "flowMember" || context.kind === "flowBinding" || context.kind === "flowGraph" ? [{ name: "id", type: "string" }] : null;
@@ -49490,7 +49542,7 @@ var init_project_source_type_checker = __esm({
49490
49542
  "Localization",
49491
49543
  "LocalizationStatus",
49492
49544
  "NeoPriorityGroup",
49493
- "PriorityOption",
49545
+ "NeoPriorityOption",
49494
49546
  "NeoDialogueGroup",
49495
49547
  "ImageRegistry",
49496
49548
  "AudioClipRegistry",
@@ -49944,7 +49996,18 @@ function collectDeclarationSymbols(uri, document, declaration, symbols, diagnost
49944
49996
  }
49945
49997
  function collectGlobalChildSymbols(uri, document, declaration, symbols, diagnostics) {
49946
49998
  if (declaration.type.name === "Root") return;
49999
+ const priorityGroup = declaration.type.name === "NeoPriorityGroup";
49947
50000
  for (const entry of collectGlobalChildEntries(document.syntax, declaration)) {
50001
+ if (priorityGroup && entry.typeName !== "NeoPriorityOption") {
50002
+ diagnostics.push({
50003
+ uri,
50004
+ range: entry.typeRange,
50005
+ severity: "error",
50006
+ source: "neo-project",
50007
+ code: "unknown-project-type",
50008
+ message: renamedDialogueTypeMessage(entry.typeName, "value") ?? `Priority group options are declared as \`NeoPriorityOption\`, not \`${entry.typeName}\`.`
50009
+ });
50010
+ }
49948
50011
  collectSymbol(
49949
50012
  uri,
49950
50013
  "graphChild",
@@ -50416,7 +50479,7 @@ var init_project_source_analysis = __esm({
50416
50479
  "Localization",
50417
50480
  "LocalizationStatus",
50418
50481
  "NeoPriorityGroup",
50419
- "PriorityOption",
50482
+ "NeoPriorityOption",
50420
50483
  "NeoDialogueGroup",
50421
50484
  "ImageRegistry",
50422
50485
  "AudioClipRegistry",
@@ -51626,7 +51689,7 @@ var init_registry = __esm({
51626
51689
  "../packages/manifest/schema-contract/registry.mjs"() {
51627
51690
  "use strict";
51628
51691
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
51629
- cliVersion: "0.73.0",
51692
+ cliVersion: "0.73.2",
51630
51693
  projectFileUploadBatchSize: 32,
51631
51694
  documentRecords: {
51632
51695
  member: {
@@ -66482,11 +66545,7 @@ function lowerClass(context, declaration) {
66482
66545
  const schema = {};
66483
66546
  const schemaKeyOrder = [];
66484
66547
  for (const memberDeclaration of declaration.members) {
66485
- const memberId = materializedId(
66486
- memberDeclaration,
66487
- "member",
66488
- `${declaration.name}.${memberDeclaration.name}`
66489
- );
66548
+ const memberId = materializedMemberId(declaration, memberDeclaration);
66490
66549
  schema[memberDeclaration.name] = memberId;
66491
66550
  schemaKeyOrder.push(memberDeclaration.name);
66492
66551
  const placement = { classId: id2, schemaKey: memberDeclaration.name };
@@ -67541,11 +67600,7 @@ function lowerInterface(context, declaration) {
67541
67600
  const id2 = materializedId(declaration, "interface", declaration.name);
67542
67601
  const base = context.baseInterfaces.get(id2);
67543
67602
  const members = declaration.members.map((member) => {
67544
- const memberId = materializedId(
67545
- member,
67546
- "interface-member",
67547
- `${declaration.name}.${member.name}`
67548
- );
67603
+ const memberId = materializedMemberId(declaration, member);
67549
67604
  const source = sourceIdentity(member, "interfaceMember", member.name);
67550
67605
  const accessModifier = effectiveSourceAccessModifier(
67551
67606
  member.modifiers,
@@ -68814,11 +68869,7 @@ function effectiveMemberIdByName(context, startClassId, name) {
68814
68869
  (member) => member.name === name
68815
68870
  );
68816
68871
  if (sourceMember !== void 0) {
68817
- return materializedId(
68818
- sourceMember,
68819
- "member",
68820
- `${sourceClass.name}.${sourceMember.name}`
68821
- );
68872
+ return materializedMemberId(sourceClass, sourceMember);
68822
68873
  }
68823
68874
  const sourceBase = sourceClass.baseTypes.find(
68824
68875
  (entry) => context.classIdsByName.has(entry.name)
@@ -70188,7 +70239,7 @@ function emitPriorityGroup(data, recordId, name) {
70188
70239
  }
70189
70240
  assertMemberIdentifier2(option.name, "priority option");
70190
70241
  return ` @id(${quote2(option.id)})
70191
- PriorityOption ${option.name} = new();`;
70242
+ NeoPriorityOption ${option.name} = new();`;
70192
70243
  });
70193
70244
  const annotations = [
70194
70245
  `@id(${quote2(recordId)})`,
@@ -71071,7 +71122,7 @@ var init_supplemental_records = __esm({
71071
71122
  init_project_file_source();
71072
71123
  init_source_format();
71073
71124
  init_ui_action_source();
71074
- PRIORITY_OPTION_PATTERN = /^(?:@id\(\s*"((?:[^"\\]|\\.)+)"\s*\)\s*)?PriorityOption\s+([A-Za-z_][A-Za-z0-9_]*)\s*=\s*new\s*\(\s*\)\s*;/;
71125
+ PRIORITY_OPTION_PATTERN = /^(?:@id\(\s*"((?:[^"\\]|\\.)+)"\s*\)\s*)?[A-Za-z_][A-Za-z0-9_]*\s+([A-Za-z_][A-Za-z0-9_]*)\s*=\s*new\s*\(\s*\)\s*;/;
71075
71126
  }
71076
71127
  });
71077
71128
 
@@ -72496,10 +72547,10 @@ function lowerDialogueGroupSettings(context, member, base) {
72496
72547
  member.arguments,
72497
72548
  "priority"
72498
72549
  );
72499
- const priorityOptionId = priorityExpression === null ? null : referenceId3(priorityExpression, "PriorityOption");
72550
+ const priorityOptionId = priorityExpression === null ? null : referenceId3(priorityExpression, "NeoPriorityOption");
72500
72551
  if (priorityExpression !== null && priorityOptionId === null) {
72501
72552
  throw dialogueSourceError(
72502
- 'Trigger priority must be authored as Reference<PriorityOption>(id: "...").',
72553
+ 'Trigger priority must be authored as Reference<NeoPriorityOption>(id: "...").',
72503
72554
  prioritySource
72504
72555
  );
72505
72556
  }
@@ -73034,7 +73085,7 @@ function globalIds2(globals, kind) {
73034
73085
  return new Map(
73035
73086
  globals.map((global) => [
73036
73087
  global.name,
73037
- schemaIdentityId(global, kind, global.name)
73088
+ materializedId(global, kind, global.name)
73038
73089
  ])
73039
73090
  );
73040
73091
  }
@@ -73047,9 +73098,6 @@ function sourceId2(source, kind, name) {
73047
73098
  name
73048
73099
  );
73049
73100
  }
73050
- function schemaIdentityId(source, kind, name) {
73051
- return source.id ?? `__pending__:${kind}:${encodeURIComponent(source.source.uri)}:${source.source.range.start.line}:${source.source.range.start.character}:${encodeURIComponent(name)}`;
73052
- }
73053
73101
  function pendingId(kind, uri, owner, ordinal, name) {
73054
73102
  return `__pending__:${kind}:${encodeURIComponent(uri)}:${encodeURIComponent(owner)}:${ordinal}:${encodeURIComponent(name)}`;
73055
73103
  }
@@ -73092,6 +73140,7 @@ var SourceSchemaIndex;
73092
73140
  var init_dialogue_lower = __esm({
73093
73141
  "src/project-source/dialogue-lower.ts"() {
73094
73142
  "use strict";
73143
+ init_lower_support();
73095
73144
  init_dialogue_source_names();
73096
73145
  init_dialogue_group_paths();
73097
73146
  init_local_values();
@@ -73125,7 +73174,7 @@ var init_dialogue_lower = __esm({
73125
73174
  );
73126
73175
  this.classesById = new Map(
73127
73176
  analysis.schema.classes.map((entry) => [
73128
- schemaIdentityId(entry, "class", entry.name),
73177
+ materializedId(entry, "class", entry.name),
73129
73178
  entry
73130
73179
  ])
73131
73180
  );
@@ -73134,7 +73183,7 @@ var init_dialogue_lower = __esm({
73134
73183
  );
73135
73184
  this.interfacesById = new Map(
73136
73185
  analysis.schema.interfaces.map((entry) => [
73137
- schemaIdentityId(entry, "interface", entry.name),
73186
+ materializedId(entry, "interface", entry.name),
73138
73187
  entry
73139
73188
  ])
73140
73189
  );
@@ -73142,20 +73191,18 @@ var init_dialogue_lower = __esm({
73142
73191
  analysis.schema.enums.map((entry) => [entry.name, entry])
73143
73192
  );
73144
73193
  this.memberNamesById = new Map(
73145
- [
73146
- ...analysis.schema.classes.flatMap((entry) => entry.members),
73147
- ...analysis.schema.interfaces.flatMap((entry) => entry.members)
73148
- ].map((member) => [
73149
- schemaIdentityId(member, "member", member.name),
73150
- member.name
73151
- ])
73194
+ [...analysis.schema.classes, ...analysis.schema.interfaces].flatMap(
73195
+ (owner) => owner.members.map(
73196
+ (member) => [materializedMemberId(owner, member), member.name]
73197
+ )
73198
+ )
73152
73199
  );
73153
73200
  this.staticMemberExpressionsById = new Map(
73154
73201
  analysis.schema.classes.flatMap(
73155
73202
  (schemaClass2) => schemaClass2.members.flatMap(
73156
73203
  (member) => member.modifiers.includes("static") ? [
73157
73204
  [
73158
- schemaIdentityId(member, "member", member.name),
73205
+ materializedMemberId(schemaClass2, member),
73159
73206
  `${schemaClass2.name}.${member.name}`
73160
73207
  ]
73161
73208
  ] : []
@@ -73166,7 +73213,7 @@ var init_dialogue_lower = __esm({
73166
73213
  analysis.schema.enums.flatMap(
73167
73214
  (schemaEnum) => schemaEnum.options.map(
73168
73215
  (option) => [
73169
- schemaIdentityId(option, "enum-option", option.name),
73216
+ materializedId(option, "enum-option", option.name),
73170
73217
  option.name
73171
73218
  ]
73172
73219
  )
@@ -73230,13 +73277,13 @@ var init_dialogue_lower = __esm({
73230
73277
  };
73231
73278
  }
73232
73279
  classMember(schemaClass2, receiver, name, visited) {
73233
- const classId = schemaIdentityId(schemaClass2, "class", schemaClass2.name);
73280
+ const classId = materializedId(schemaClass2, "class", schemaClass2.name);
73234
73281
  if (visited.has(classId)) return null;
73235
73282
  visited.add(classId);
73236
73283
  const generics = this.genericEnvironment(schemaClass2, receiver);
73237
73284
  const own = schemaClass2.members.find((member) => member.name === name);
73238
73285
  if (own !== void 0) {
73239
- return this.resolvedMember(own, generics, true);
73286
+ return this.resolvedMember(schemaClass2, own, generics);
73240
73287
  }
73241
73288
  for (const base of schemaClass2.baseTypes) {
73242
73289
  const parent = this.classesByName.get(base.name);
@@ -73249,7 +73296,7 @@ var init_dialogue_lower = __esm({
73249
73296
  return null;
73250
73297
  }
73251
73298
  interfaceMember(schemaInterface, name, visited) {
73252
- const interfaceId = schemaIdentityId(
73299
+ const interfaceId = materializedId(
73253
73300
  schemaInterface,
73254
73301
  "interface",
73255
73302
  schemaInterface.name
@@ -73257,7 +73304,8 @@ var init_dialogue_lower = __esm({
73257
73304
  if (visited.has(interfaceId)) return null;
73258
73305
  visited.add(interfaceId);
73259
73306
  const own = schemaInterface.members.find((member) => member.name === name);
73260
- if (own !== void 0) return this.resolvedMember(own, /* @__PURE__ */ new Map(), false);
73307
+ if (own !== void 0)
73308
+ return this.resolvedMember(schemaInterface, own, /* @__PURE__ */ new Map());
73261
73309
  for (const base of schemaInterface.baseTypes) {
73262
73310
  const parent = this.interfacesByName.get(base.name);
73263
73311
  if (parent === void 0) continue;
@@ -73266,13 +73314,13 @@ var init_dialogue_lower = __esm({
73266
73314
  }
73267
73315
  return null;
73268
73316
  }
73269
- resolvedMember(member, generics, classPropertyIsGetter) {
73317
+ resolvedMember(owner, member, generics) {
73270
73318
  if (member.kind === "function") return null;
73271
73319
  const typeInfo = this.typeInfoForManifestType(member.type, generics);
73272
73320
  if (typeInfo === null) return null;
73273
73321
  return {
73274
- kind: classPropertyIsGetter && member.kind === "property" ? "getter" : "stored",
73275
- memberId: schemaIdentityId(member, "member", member.name),
73322
+ kind: owner.kind === "class" && member.kind === "property" ? "getter" : "stored",
73323
+ memberId: materializedMemberId(owner, member),
73276
73324
  schemaKey: member.name,
73277
73325
  typeInfo
73278
73326
  };
@@ -73280,7 +73328,7 @@ var init_dialogue_lower = __esm({
73280
73328
  genericEnvironment(schemaClass2, receiver) {
73281
73329
  const result = /* @__PURE__ */ new Map();
73282
73330
  for (const parameter4 of schemaClass2.genericParameters) {
73283
- const parameterId = schemaIdentityId(
73331
+ const parameterId = materializedId(
73284
73332
  parameter4.identity,
73285
73333
  "generic-parameter",
73286
73334
  `${schemaClass2.name}.${parameter4.name}`
@@ -73333,12 +73381,12 @@ var init_dialogue_lower = __esm({
73333
73381
  type: type.name === "Dictionary" ? 5 /* Dictionary */ : 6 /* List */,
73334
73382
  required: required2,
73335
73383
  entryTypeInfo,
73336
- ...keyEnum === void 0 ? {} : { keyEnumId: schemaIdentityId(keyEnum, "enum", keyEnum.name) }
73384
+ ...keyEnum === void 0 ? {} : { keyEnumId: materializedId(keyEnum, "enum", keyEnum.name) }
73337
73385
  };
73338
73386
  }
73339
73387
  const schemaClass2 = this.classesByName.get(type.name);
73340
73388
  if (schemaClass2 !== void 0) {
73341
- const classId = schemaIdentityId(schemaClass2, "class", schemaClass2.name);
73389
+ const classId = materializedId(schemaClass2, "class", schemaClass2.name);
73342
73390
  const typeArguments = Object.fromEntries(
73343
73391
  schemaClass2.genericParameters.flatMap((parameter4, index) => {
73344
73392
  const argument2 = type.arguments[index];
@@ -73347,7 +73395,7 @@ var init_dialogue_lower = __esm({
73347
73395
  if (argumentType === null) return [];
73348
73396
  return [
73349
73397
  [
73350
- schemaIdentityId(
73398
+ materializedId(
73351
73399
  parameter4.identity,
73352
73400
  "generic-parameter",
73353
73401
  `${schemaClass2.name}.${parameter4.name}`
@@ -73368,7 +73416,7 @@ var init_dialogue_lower = __esm({
73368
73416
  if (neoInterface !== void 0) {
73369
73417
  return {
73370
73418
  type: 22 /* Interface */,
73371
- interfaceId: schemaIdentityId(
73419
+ interfaceId: materializedId(
73372
73420
  neoInterface,
73373
73421
  "interface",
73374
73422
  neoInterface.name
@@ -73380,7 +73428,7 @@ var init_dialogue_lower = __esm({
73380
73428
  if (neoEnum !== void 0) {
73381
73429
  return {
73382
73430
  type: 8 /* Enum */,
73383
- enumId: schemaIdentityId(neoEnum, "enum", neoEnum.name),
73431
+ enumId: materializedId(neoEnum, "enum", neoEnum.name),
73384
73432
  required: required2
73385
73433
  };
73386
73434
  }
@@ -106545,6 +106593,67 @@ var init_project_commit_preparation_scoped_loader = __esm({
106545
106593
  }
106546
106594
  });
106547
106595
 
106596
+ // ../src/database/lookup-target-class-contract.ts
106597
+ function lookupTargetClassContractViolation(args) {
106598
+ const actualClassId = typeof args.targetClassId === "string" ? args.targetClassId : null;
106599
+ if (actualClassId === null) return null;
106600
+ const classById = args.schemaIndex.classesById;
106601
+ if (!classById.has(actualClassId)) return null;
106602
+ const entryClassId = lookupEntryClassId(
106603
+ args.member,
106604
+ args.schemaIndex.membersById
106605
+ );
106606
+ if (entryClassId !== null && classById.has(entryClassId) && !args.schemaIndex.classIsOrExtends(actualClassId, entryClassId)) {
106607
+ return `lookup member ${args.member.name} target ${args.targetValueId} is ${classDisplayName(actualClassId, classById)}, but collection ${collectionMemberName(args.member, args.schemaIndex)} holds ${classDisplayName(entryClassId, classById)}.`;
106608
+ }
106609
+ const declaredClassId = lookupDeclaredClassId(args.member, classById);
106610
+ if (declaredClassId !== null && !args.schemaIndex.classIsOrExtends(actualClassId, declaredClassId)) {
106611
+ const narrowedFrom = entryClassId === null || !classById.has(entryClassId) ? `the collection ${collectionMemberName(args.member, args.schemaIndex)}` : `the collection ${collectionMemberName(args.member, args.schemaIndex)} holds ${classDisplayName(entryClassId, classById)}`;
106612
+ return `lookup member ${args.member.name} target ${args.targetValueId} is ${classDisplayName(actualClassId, classById)}, but the member declares ${classDisplayName(declaredClassId, classById)} \u2014 ${narrowedFrom} and this member narrows it. Point it at a ${classDisplayName(declaredClassId, classById)} row.`;
106613
+ }
106614
+ return null;
106615
+ }
106616
+ function lookupEntryClassId(member, memberById2) {
106617
+ const collection = memberById2.get(member.collectionMemberId);
106618
+ if (collection === void 0) return null;
106619
+ if (!isMemberListBase(collection) && !isMemberDictionaryBase(collection)) {
106620
+ return null;
106621
+ }
106622
+ const entry = memberById2.get(collection.entryMemberId);
106623
+ if (entry === void 0) return null;
106624
+ return isMemberClassBase(entry) ? entry.classId : null;
106625
+ }
106626
+ function lookupDeclaredClassId(member, classById) {
106627
+ const declared = member.declaredTypeInfo;
106628
+ if (declared === void 0) return null;
106629
+ if (declared === null) return null;
106630
+ if (declared.type !== 7 /* Class */) return null;
106631
+ return classById.has(declared.classId) ? declared.classId : null;
106632
+ }
106633
+ function classDisplayName(classId, classById) {
106634
+ return classById.get(classId)?.name ?? classId;
106635
+ }
106636
+ function collectionMemberName(member, schemaIndex) {
106637
+ const collection = schemaIndex.membersById.get(member.collectionMemberId);
106638
+ if (collection === void 0) return member.collectionMemberId;
106639
+ const owner = schemaIndex.schemaPlacementsByMemberId.get(collection.id)?.[0]?.ownerClass;
106640
+ return owner ? `${owner.name}.${collection.name}` : collection.name;
106641
+ }
106642
+ function lookupDeclaredClassContractViolation(member, schemaIndex) {
106643
+ const declared = lookupDeclaredClassId(member, schemaIndex.classesById);
106644
+ const entry = lookupEntryClassId(member, schemaIndex.membersById);
106645
+ if (declared === null || entry === null || !schemaIndex.classesById.has(entry))
106646
+ return null;
106647
+ if (schemaIndex.classIsOrExtends(declared, entry)) return null;
106648
+ return `Lookup member ${member.name} declares ${classDisplayName(declared, schemaIndex.classesById)}, but collection ${collectionMemberName(member, schemaIndex)} holds ${classDisplayName(entry, schemaIndex.classesById)}.`;
106649
+ }
106650
+ var init_lookup_target_class_contract = __esm({
106651
+ "../src/database/lookup-target-class-contract.ts"() {
106652
+ "use strict";
106653
+ init_member_kinds();
106654
+ }
106655
+ });
106656
+
106548
106657
  // ../src/models/dialogue-context-resolver.ts
106549
106658
  function resolveDialoguePrimaryValueId(dialogue) {
106550
106659
  return dialogue.primaryLinkedValueId ?? null;
@@ -110112,76 +110221,6 @@ var init_project_document_value_overlay = __esm({
110112
110221
  }
110113
110222
  });
110114
110223
 
110115
- // ../src/database/lookup-target-class-contract.ts
110116
- function lookupTargetClassContractViolation(args) {
110117
- const actualClassId = typeof args.targetClassId === "string" ? args.targetClassId : null;
110118
- if (actualClassId === null) return null;
110119
- const classById = new Map(
110120
- args.classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
110121
- );
110122
- if (!classById.has(actualClassId)) return null;
110123
- const entryClassId = lookupEntryClassId(args.member, args.memberById);
110124
- const collectionName = collectionMemberName(
110125
- args.member,
110126
- args.memberById,
110127
- args.classes
110128
- );
110129
- if (entryClassId !== null && classById.has(entryClassId) && !classAssignableToClass(actualClassId, entryClassId, classById)) {
110130
- return `lookup member ${args.member.name} target ${args.targetValueId} is ${classDisplayName(actualClassId, classById)}, but collection ${collectionName} holds ${classDisplayName(entryClassId, classById)}.`;
110131
- }
110132
- const declaredClassId = lookupDeclaredClassId(args.member, classById);
110133
- if (declaredClassId !== null && !classAssignableToClass(actualClassId, declaredClassId, classById)) {
110134
- const narrowedFrom = entryClassId === null || !classById.has(entryClassId) ? `the collection ${collectionName}` : `the collection ${collectionName} holds ${classDisplayName(entryClassId, classById)}`;
110135
- return `lookup member ${args.member.name} target ${args.targetValueId} is ${classDisplayName(actualClassId, classById)}, but the member declares ${classDisplayName(declaredClassId, classById)} \u2014 ${narrowedFrom} and this member narrows it. Point it at a ${classDisplayName(declaredClassId, classById)} row.`;
110136
- }
110137
- return null;
110138
- }
110139
- function lookupEntryClassId(member, memberById2) {
110140
- const collection = memberById2.get(member.collectionMemberId);
110141
- if (collection === void 0) return null;
110142
- if (!isMemberListBase(collection) && !isMemberDictionaryBase(collection)) {
110143
- return null;
110144
- }
110145
- const entry = memberById2.get(collection.entryMemberId);
110146
- if (entry === void 0) return null;
110147
- return isMemberClassBase(entry) ? entry.classId : null;
110148
- }
110149
- function lookupDeclaredClassId(member, classById) {
110150
- const declared = member.declaredTypeInfo;
110151
- if (declared === void 0) return null;
110152
- if (declared === null) return null;
110153
- if (declared.type !== 7 /* Class */) return null;
110154
- return classById.has(declared.classId) ? declared.classId : null;
110155
- }
110156
- function classAssignableToClass(actualClassId, expectedClassId, classById) {
110157
- const visited = /* @__PURE__ */ new Set();
110158
- let current = actualClassId;
110159
- while (current !== void 0 && !visited.has(current)) {
110160
- if (current === expectedClassId) return true;
110161
- visited.add(current);
110162
- current = classById.get(current)?.extendsClassId;
110163
- }
110164
- return false;
110165
- }
110166
- function classDisplayName(classId, classById) {
110167
- return classById.get(classId)?.name ?? classId;
110168
- }
110169
- function collectionMemberName(member, memberById2, classes) {
110170
- const collection = memberById2.get(member.collectionMemberId);
110171
- if (collection === void 0) return member.collectionMemberId;
110172
- const owner = classes.find(
110173
- (schemaClass2) => Object.values(schemaClass2.schema).includes(member.collectionMemberId)
110174
- );
110175
- if (owner === void 0) return collection.name;
110176
- return `${owner.name}.${collection.name}`;
110177
- }
110178
- var init_lookup_target_class_contract = __esm({
110179
- "../src/database/lookup-target-class-contract.ts"() {
110180
- "use strict";
110181
- init_member_kinds();
110182
- }
110183
- });
110184
-
110185
110224
  // ../src/database/stored-value-graph-semantics.ts
110186
110225
  function inspectStoredValueNode(options) {
110187
110226
  try {
@@ -111009,8 +111048,7 @@ var init_project_version_static_value_writes = __esm({
111009
111048
  member: dependency.member,
111010
111049
  targetValueId: targetId,
111011
111050
  targetClassId: target.classId ?? null,
111012
- memberById: this.schemaIndex.membersById,
111013
- classes: this.schemaIndex.classes
111051
+ schemaIndex: this.schemaIndex
111014
111052
  });
111015
111053
  if (violation !== null) throw new Error(`${path} ${violation}`);
111016
111054
  }
@@ -114335,7 +114373,10 @@ function hasAuthoredNeoScriptBody(member) {
114335
114373
  function assertConstructedGraphReferencesResolve(args) {
114336
114374
  const sites = collectTouchedInitializerSites(args);
114337
114375
  if (sites.length === 0) return;
114338
- const valueIds = new Set(args.document.values.map((value) => value.id));
114376
+ const valueById = new Map(
114377
+ args.document.values.map((value) => [value.id, value])
114378
+ );
114379
+ const schemaIndex = projectSchemaIndexFor(args.document);
114339
114380
  for (const site of sites) {
114340
114381
  if ((site.init.compiled?.parameters.length ?? 2) > 2) continue;
114341
114382
  if (site.sourceValueId === void 0 && [
@@ -114359,7 +114400,8 @@ function assertConstructedGraphReferencesResolve(args) {
114359
114400
  site,
114360
114401
  produced,
114361
114402
  createdValues,
114362
- documentValueIds: valueIds
114403
+ documentValuesById: valueById,
114404
+ schemaIndex
114363
114405
  });
114364
114406
  }
114365
114407
  }
@@ -114423,7 +114465,6 @@ function collectTouchedInitializerSites(args) {
114423
114465
  return sites;
114424
114466
  }
114425
114467
  function assertProducedGraphLookupsResolve(args) {
114426
- if (args.createdValues.length === 0) return;
114427
114468
  const rootMember = args.produced.classId === null ? args.site.member : { ...args.site.member, classId: args.produced.classId };
114428
114469
  const graphValues = args.createdValues;
114429
114470
  const rootRow = {
@@ -114449,20 +114490,28 @@ function assertProducedGraphLookupsResolve(args) {
114449
114490
  new Set(args.createdValues.map((value) => value.id)),
114450
114491
  [{ member: rootMember, valueId: rootRow.id }]
114451
114492
  );
114452
- const resolvableIds = /* @__PURE__ */ new Set([
114453
- ...args.documentValueIds,
114454
- ...args.createdValues.map((value) => value.id)
114455
- ]);
114456
- for (const row of args.createdValues) {
114457
- const member = ownerByValueId.get(row.id);
114458
- if (member === void 0 || member.kind !== 9 /* Lookup */) continue;
114493
+ const createdById = new Map(graphValues.map((value) => [value.id, value]));
114494
+ createdById.set(rootRow.id, rootRow);
114495
+ for (const row of createdById.values()) {
114496
+ const member = row === rootRow ? rootMember : ownerByValueId.get(row.id);
114497
+ if (member === void 0 || !isMemberLookupBase(member)) continue;
114459
114498
  if (!Array.isArray(row.value)) continue;
114460
114499
  for (const targetId of row.value) {
114461
114500
  if (typeof targetId !== "string") continue;
114462
- if (resolvableIds.has(targetId)) continue;
114463
- throw new Error(
114464
- `${args.site.label} constructs "${member.name}" pointing at value "${targetId}", which the construction does not produce and this project version does not contain.`
114465
- );
114501
+ const target = createdById.get(targetId) ?? args.documentValuesById.get(targetId) ?? initializerEvaluatorLookups(args.document).valueById(targetId);
114502
+ if (target === void 0 || target === null) {
114503
+ throw new Error(
114504
+ `${args.site.label} constructs "${member.name}" pointing at value "${targetId}", which the construction does not produce and this project version does not contain.`
114505
+ );
114506
+ }
114507
+ const violation = lookupTargetClassContractViolation({
114508
+ member,
114509
+ targetValueId: targetId,
114510
+ targetClassId: target.classId,
114511
+ schemaIndex: args.schemaIndex
114512
+ });
114513
+ if (violation !== null)
114514
+ throw new Error(`${args.site.label} ${violation}`);
114466
114515
  }
114467
114516
  }
114468
114517
  }
@@ -115453,6 +115502,9 @@ var SERVER_COMPILATION_PROJECT_CACHE_LIMIT, serverCompilationProjectCache, READ_
115453
115502
  var init_project_version_schema_commit = __esm({
115454
115503
  "../src/database/project-version-schema-commit.ts"() {
115455
115504
  "use strict";
115505
+ init_member_kinds();
115506
+ init_project_schema_index();
115507
+ init_lookup_target_class_contract();
115456
115508
  init_dialogue_logic_compile_pure();
115457
115509
  init_neoscript_compiler_revision();
115458
115510
  init_neoscript_source_catalog();
@@ -121188,6 +121240,19 @@ function assertProjectVersionWholeGraphWritesValid(args) {
121188
121240
  assertStagedUnorderedContainmentValid(args.document, projected, changes);
121189
121241
  assertWorldFootprintEntryTypes(projected, changes);
121190
121242
  assertStagedSchemaIdentifiersValid(projected, changes);
121243
+ if (changes.some(
121244
+ (change) => change.recordKind === "member" || change.recordKind === "class"
121245
+ )) {
121246
+ const schemaIndex = projectSchemaIndexFor(projected);
121247
+ for (const member of projected.members) {
121248
+ if (!isMemberLookupBase(member)) continue;
121249
+ const violation = lookupDeclaredClassContractViolation(
121250
+ member,
121251
+ schemaIndex
121252
+ );
121253
+ if (violation !== null) throw new Error(violation);
121254
+ }
121255
+ }
121191
121256
  assertStagedActionListenersValid(projected, changes);
121192
121257
  assertStagedUserDelegateTargetsValid(projected, changes);
121193
121258
  assertAuthoredMemberChangeListenersValid(args.document, projected, changes);
@@ -122402,6 +122467,9 @@ var KNOWN_TRANSACTION_OPERATIONS, INTERFACE_VALIDATED_RECORD_KINDS, ACTION_LISTE
122402
122467
  var init_project_version_whole_graph_validation = __esm({
122403
122468
  "../src/database/project-version-whole-graph-validation.ts"() {
122404
122469
  "use strict";
122470
+ init_member_kinds();
122471
+ init_project_schema_index();
122472
+ init_lookup_target_class_contract();
122405
122473
  init_project_root_members();
122406
122474
  init_neoscript_source_catalog();
122407
122475
  init_canonical_json();
@@ -129650,7 +129718,7 @@ function constructedClass(context, member, expression, currentClassId, path) {
129650
129718
  return target;
129651
129719
  }
129652
129720
  function assertConstructedClassAssignable(context, named, member, path) {
129653
- if (classAssignableToClass2(context, named.id, member.classId)) return;
129721
+ if (classAssignableToClass(context, named.id, member.classId)) return;
129654
129722
  const declaredName = context.classes.get(member.classId)?.name ?? member.classId;
129655
129723
  throw new Error(
129656
129724
  `Class value ${path} constructs ${named.name}, which does not descend from the declared class ${declaredName}.`
@@ -130356,13 +130424,13 @@ function validateReferenceContract(context, member, target, ownerValueId) {
130356
130424
  const expectedTypeName = lookupEntryTypeName(context, member);
130357
130425
  const targetData = valueData(context, target.id);
130358
130426
  const actualClassId = targetData && typeof targetData.classId === "string" ? targetData.classId : null;
130359
- if (expectedClassId && actualClassId && !classAssignableToClass2(context, actualClassId, expectedClassId)) {
130427
+ if (expectedClassId && actualClassId && !classAssignableToClass(context, actualClassId, expectedClassId)) {
130360
130428
  throw new Error(
130361
130429
  `Lookup member ${member.name} target ${target.id} is ${classDisplayName2(context, actualClassId)}, but collection ${collectionMemberName2(context, member)} holds ${classDisplayName2(context, expectedClassId)}.`
130362
130430
  );
130363
130431
  }
130364
130432
  const declaredClassId = lookupDeclaredClassId2(context, member);
130365
- if (declaredClassId && actualClassId && !classAssignableToClass2(context, actualClassId, declaredClassId)) {
130433
+ if (declaredClassId && actualClassId && !classAssignableToClass(context, actualClassId, declaredClassId)) {
130366
130434
  const narrowedFrom = expectedClassId === null ? `the collection ${collectionMemberName2(context, member)}` : `the collection ${collectionMemberName2(context, member)} holds ${classDisplayName2(context, expectedClassId)}`;
130367
130435
  throw new Error(
130368
130436
  `Lookup member ${member.name} target ${target.id} is ${classDisplayName2(context, actualClassId)}, but the member declares ${classDisplayName2(context, declaredClassId)} \u2014 ${narrowedFrom} and this member narrows it. Point it at a ${classDisplayName2(context, declaredClassId)} row.`
@@ -130422,7 +130490,7 @@ function referenceTypeNameAssignable(context, actualName, expectedName) {
130422
130490
  const actualClass = context.classesByName.get(actualName);
130423
130491
  const expectedClass = context.classesByName.get(expectedName);
130424
130492
  if (actualClass && expectedClass) {
130425
- return classAssignableToClass2(context, actualClass.id, expectedClass.id);
130493
+ return classAssignableToClass(context, actualClass.id, expectedClass.id);
130426
130494
  }
130427
130495
  const expectedInterfaceId = context.interfaceIdsByName.get(expectedName);
130428
130496
  return actualClass && expectedInterfaceId ? classImplementsInterface2(
@@ -130706,7 +130774,7 @@ function lookupEntryClassId2(context, member) {
130706
130774
  const entry = collection?.kind === "list" || collection?.kind === "dictionary" ? context.members.get(collection.entryMemberId) : null;
130707
130775
  return entry?.kind === "class" ? entry.classId : null;
130708
130776
  }
130709
- function classAssignableToClass2(context, actualClassId, expectedClassId) {
130777
+ function classAssignableToClass(context, actualClassId, expectedClassId) {
130710
130778
  let current = actualClassId;
130711
130779
  const visited = /* @__PURE__ */ new Set();
130712
130780
  while (current && !visited.has(current)) {
@@ -135954,11 +136022,7 @@ function lowerProjectSchemaV4(base, analysis, options = {}) {
135954
136022
  analysis.schema.classes.flatMap(
135955
136023
  (ownerClass) => ownerClass.members.map(
135956
136024
  (member) => [
135957
- materializedId(
135958
- member,
135959
- "member",
135960
- `${ownerClass.name}.${member.name}`
135961
- ),
136025
+ materializedMemberId(ownerClass, member),
135962
136026
  { ownerClass, member }
135963
136027
  ]
135964
136028
  )
@@ -137416,7 +137480,7 @@ function emitTrigger(context, node) {
137416
137480
  if (optionId) {
137417
137481
  args.push([
137418
137482
  "priority",
137419
- `Reference<PriorityOption>(id: ${quote5(optionId)})`
137483
+ `Reference<NeoPriorityOption>(id: ${quote5(optionId)})`
137420
137484
  ]);
137421
137485
  }
137422
137486
  }
@@ -137661,6 +137725,7 @@ function emitProse(context, textId, rawVariables, nodeBindings, primaryAlias) {
137661
137725
  );
137662
137726
  const variables = isObjectRecord2(rawVariables) ? rawVariables : {};
137663
137727
  const pieces = [];
137728
+ let pointerResolver;
137664
137729
  let cursor = 0;
137665
137730
  const pattern = /\{\{neo-var:([^}]+)\}\}/g;
137666
137731
  for (let match = pattern.exec(text); match !== null; match = pattern.exec(text)) {
@@ -137672,12 +137737,25 @@ function emitProse(context, textId, rawVariables, nodeBindings, primaryAlias) {
137672
137737
  cursor = pattern.lastIndex;
137673
137738
  continue;
137674
137739
  }
137675
- const sourcePath = authoredVariablePath(
137676
- variable2.sourcePath,
137677
- nodeBindings,
137678
- context.bindings,
137679
- context.memberNames
137680
- );
137740
+ let sourcePath;
137741
+ if (isObjectRecord2(variable2.pointer) && variable2.pointer.type !== "value" && variable2.sourcePath.includes(".@getter:") || variable2.sourcePath.startsWith(`ref:${PENDING_ID_PREFIX}`) || variable2.sourcePath.startsWith(`linked:${PENDING_ID_PREFIX}`)) {
137742
+ pointerResolver ??= {
137743
+ primaryAlias,
137744
+ bindingNameByValueId: {
137745
+ get: (valueId) => (nodeBindings.get(valueId) ?? context.bindings.get(valueId))?.name
137746
+ },
137747
+ memberNameById: context.memberNames,
137748
+ staticMemberExpressionById: context.staticMemberExpressions,
137749
+ enumOptionNameById: context.enumOptionNames
137750
+ };
137751
+ sourcePath = pointerSource2(variable2.pointer, pointerResolver);
137752
+ } else {
137753
+ sourcePath = authoredVariablePath(
137754
+ variable2.sourcePath,
137755
+ nodeBindings,
137756
+ context.bindings
137757
+ );
137758
+ }
137681
137759
  if (sourcePath === null) {
137682
137760
  pieces.push(`{MissingVariable(${quote5(variableId)})}`);
137683
137761
  cursor = pattern.lastIndex;
@@ -137722,27 +137800,14 @@ function recoverableProse(context, textId, rawVariables, owner, nodeBindings, pr
137722
137800
  return { source: recoveryProse(reason), reason };
137723
137801
  }
137724
137802
  }
137725
- function authoredVariablePath(sourcePath, nodeBindings, dialogueBindings, memberNames) {
137803
+ function authoredVariablePath(sourcePath, nodeBindings, dialogueBindings) {
137726
137804
  const persisted = PERSISTED_VARIABLE_PATH.exec(sourcePath);
137727
137805
  const lexicalPath = persisted ? (() => {
137728
137806
  const valueId = persisted[1];
137729
137807
  const binding = nodeBindings.get(valueId) ?? dialogueBindings.get(valueId);
137730
137808
  return binding ? `${binding.name}${persisted[2] ?? ""}` : null;
137731
137809
  })() : sourcePath;
137732
- if (lexicalPath === null) return null;
137733
- let missingMember = false;
137734
- const authored = lexicalPath.replace(
137735
- /\.@getter:([^.]+)/gu,
137736
- (_match, memberId) => {
137737
- const memberName = memberNames.get(memberId);
137738
- if (memberName === void 0) {
137739
- missingMember = true;
137740
- return "";
137741
- }
137742
- return `.${memberName}`;
137743
- }
137744
- );
137745
- return missingMember ? null : authored;
137810
+ return lexicalPath;
137746
137811
  }
137747
137812
  function recoveryProse(reason) {
137748
137813
  return `"""
@@ -138108,6 +138173,8 @@ var PERSISTED_VARIABLE_PATH, DIALOGUE_SYSTEM_TYPE_NAMES, ValuePlacementIndex, Un
138108
138173
  var init_dialogue_sources = __esm({
138109
138174
  "src/project-source/dialogue-sources.ts"() {
138110
138175
  "use strict";
138176
+ init_pending_id();
138177
+ init_ui_action_source();
138111
138178
  init_generated_csharp_identifiers();
138112
138179
  init_dialogue_group_symbols();
138113
138180
  init_language_spec();
@@ -151992,7 +152059,7 @@ function dialogueGroupCompletions(analysis, document, position) {
151992
152059
  items.push({
151993
152060
  label: name,
151994
152061
  kind: "enumMember",
151995
- detail: "PriorityOption",
152062
+ detail: "NeoPriorityOption",
151996
152063
  insertText: name,
151997
152064
  symbolId: option.id
151998
152065
  });
@@ -191424,7 +191491,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
191424
191491
  async function main() {
191425
191492
  const args = parseArgs(process.argv.slice(2));
191426
191493
  if (args.command === "--version") {
191427
- console.log("0.73.0");
191494
+ console.log("0.73.2");
191428
191495
  return;
191429
191496
  }
191430
191497
  if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
@@ -1609,7 +1609,8 @@ var RENAMED_DIALOGUE_TYPES = /* @__PURE__ */ new Map([
1609
1609
  { base: "NeoDialogueReference", value: "NeoDialogueReference" }
1610
1610
  ],
1611
1611
  ["DialogueGroup", { base: "NeoDialogueGroup", value: "NeoDialogueGroup" }],
1612
- ["PriorityGroup", { base: "NeoPriorityGroup", value: "NeoPriorityGroup" }]
1612
+ ["PriorityGroup", { base: "NeoPriorityGroup", value: "NeoPriorityGroup" }],
1613
+ ["PriorityOption", { base: "NeoPriorityOption", value: "NeoPriorityOption" }]
1613
1614
  ]);
1614
1615
  function renamedDialogueTypeMessage(name, position) {
1615
1616
  const replacement = RENAMED_DIALOGUE_TYPES.get(name)?.[position];
@@ -55287,7 +55288,7 @@ var SPECIALIZED_RELATION_KINDS = /* @__PURE__ */ new Set([
55287
55288
 
55288
55289
  // ../packages/manifest/schema-contract/registry.mjs
55289
55290
  var PROJECT_SCHEMA_CONTRACT = Object.freeze({
55290
- cliVersion: "0.73.0",
55291
+ cliVersion: "0.73.2",
55291
55292
  projectFileUploadBatchSize: 32,
55292
55293
  documentRecords: {
55293
55294
  member: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neocompose/cli",
3
- "version": "0.73.0",
3
+ "version": "0.73.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.73.0 -->
12
+ <!-- reviewed-through-cli: 0.73.2 -->
13
13
 
14
14
  # Neo Compose CLI
15
15
 
@@ -118,7 +118,7 @@ wrappers.
118
118
  The marker near the top of `SKILL.md` must exactly match the package version:
119
119
 
120
120
  ```html
121
- <!-- reviewed-through-cli: 0.73.0 -->
121
+ <!-- reviewed-through-cli: 0.73.2 -->
122
122
  ```
123
123
 
124
124
  The quoted version above is checked too, so this instruction cannot go stale
@@ -440,3 +440,9 @@ Populated unordered member defaults, such as `@settings(kind: .Unordered)` with
440
440
  `List<Entry> Entries = [new Entry()]`, are constructed by an initializer for
441
441
  each instance. A declaration has no container value row to own unordered entries.
442
442
  Nested unordered lists already have container rows and retain their stored values.
443
+
444
+ A lookup's declared class must be assignable to the entry class of its
445
+ `@settings(collection: Owner.Member)` collection. A subclass may narrow the
446
+ selection. Constructor arguments and member initializers must select compatible
447
+ targets too. An `NPC` lookup cannot select from `List<Quest>`, even when its
448
+ initializer is typed `NPC`; status reports the conflicting collection annotation.
@@ -283,3 +283,7 @@ Pull/push compare server-verified SHA-256, not storage ETags. A divergent
283
283
  binary keeps local bytes and writes the verified remote side under
284
284
  `.neo/conflicts/files/<file-id>/`. A retained declaration with a missing binary
285
285
  is an error; remove the declaration to request deletion.
286
+
287
+ New schema getters referenced by NeoFlow interpolation need no `@id`. Export and
288
+ `neo dev` assign the same identity to the declaration and its references, including
289
+ inherited getters. Repeated exports and the next push reuse the export identity ledger.