@neocompose/cli 0.36.9 → 0.36.10

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,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.36.10] - 2026-08-21
4
+
5
+ ### Fixed
6
+
7
+ - Apply large committed pushes again. A push big enough for the durable commit
8
+ path could commit server-side but fail its result download, leaving the
9
+ workspace reporting the same record and value seed pending forever. The
10
+ server now spreads pending-id assignments across result chunks instead of
11
+ returning them as one map, and `neo push` refuses a result download whose
12
+ record count disagrees with the committed total instead of applying a
13
+ partial result.
14
+ - Make `neo resolve --mine`/`--theirs` adopt the server side as the new base
15
+ for every conflict they settle. A stale base after resolution made the next
16
+ status plan deletions for rows the server document still contains — up to
17
+ the entire content of a just-pushed value seed.
18
+
3
19
  ## [0.36.9] - 2026-08-20
4
20
 
5
21
  ### Fixed
package/dist/neo.mjs CHANGED
@@ -82113,6 +82113,16 @@ function neoScriptMemberContractProjection(value) {
82113
82113
  defaultPresent: value.defaultValue != null
82114
82114
  };
82115
82115
  }
82116
+ function transactionImpactsAnyOwnerMember(scope, impactedIds) {
82117
+ for (const member of scope.document.members) {
82118
+ if (impactedIds.has(member.id)) return true;
82119
+ }
82120
+ for (const root of scope.roots) {
82121
+ const ownerId = Reflect.get(root.member, "id");
82122
+ if (typeof ownerId === "string" && impactedIds.has(ownerId)) return true;
82123
+ }
82124
+ return false;
82125
+ }
82116
82126
  function collectNeoScriptRecompileTargets(args) {
82117
82127
  if (args.forceRecompile === true) return completeTargets(args.postDocument);
82118
82128
  const explicit = explicitTargetIds(args.changes);
@@ -82176,15 +82186,17 @@ function collectNeoScriptRecompileTargets(args) {
82176
82186
  args.postDocument,
82177
82187
  args.postDocument.variants ?? []
82178
82188
  );
82179
- const ownerByValueId = resolveOwnerMembersForValues(
82180
- scope.document,
82181
- new Set(postValues.map((record3) => record3.id)),
82182
- scope.roots
82183
- );
82184
- for (const [valueId, owner] of ownerByValueId) {
82185
- const ownerId = Reflect.get(owner, "id");
82186
- if (typeof ownerId === "string" && impactedIds.has(ownerId)) {
82187
- valueIds.add(valueId);
82189
+ if (transactionImpactsAnyOwnerMember(scope, impactedIds)) {
82190
+ const ownerByValueId = resolveOwnerMembersForValues(
82191
+ scope.document,
82192
+ new Set(postValues.map((record3) => record3.id)),
82193
+ scope.roots
82194
+ );
82195
+ for (const [valueId, owner] of ownerByValueId) {
82196
+ const ownerId = Reflect.get(owner, "id");
82197
+ if (typeof ownerId === "string" && impactedIds.has(ownerId)) {
82198
+ valueIds.add(valueId);
82199
+ }
82188
82200
  }
82189
82201
  }
82190
82202
  }
@@ -88564,6 +88576,56 @@ var init_project_version_transaction_types = __esm({
88564
88576
  }
88565
88577
  });
88566
88578
 
88579
+ // ../src/database/project-version-relation-sweep-trigger.ts
88580
+ function stagedChangesAffectClassRelations(current, changes) {
88581
+ const classesById = new Map(
88582
+ (current.classes ?? []).map((schemaClass2) => [schemaClass2.id, schemaClass2])
88583
+ );
88584
+ const valuesById = new Map(
88585
+ (current.values ?? []).map((value) => [value.id, value])
88586
+ );
88587
+ for (const change of changes) {
88588
+ if (change.recordKind === "internal-record-relation") return true;
88589
+ if (change.recordKind === "class") {
88590
+ if (change.operation !== "update") return true;
88591
+ if (change.deleted === true) return true;
88592
+ const before2 = classesById.get(change.recordId);
88593
+ if (before2 === void 0) return true;
88594
+ const after = change.nextData;
88595
+ if (!isPlainRecord(after)) return true;
88596
+ if (before2.extendsClassId !== after.extendsClassId) return true;
88597
+ continue;
88598
+ }
88599
+ if (change.recordKind !== "value") continue;
88600
+ const before = valuesById.get(change.recordId);
88601
+ if (valueCreateCannotAffectClassRelations(change, before)) continue;
88602
+ if (relationEndpointClassId(before) !== relationEndpointClassId(change.nextData)) {
88603
+ return true;
88604
+ }
88605
+ }
88606
+ return false;
88607
+ }
88608
+ function valueCreateCannotAffectClassRelations(change, before) {
88609
+ if (change.operation !== "create") return false;
88610
+ if (change.deleted === true) return false;
88611
+ return before === void 0;
88612
+ }
88613
+ function relationEndpointClassId(record3) {
88614
+ if (!isPlainRecord(record3)) return void 0;
88615
+ if (typeof record3.classId === "string") return record3.classId;
88616
+ if (typeof record3.typeId === "string") return record3.typeId;
88617
+ return void 0;
88618
+ }
88619
+ function isPlainRecord(value) {
88620
+ if (value === null || typeof value !== "object") return false;
88621
+ return !Array.isArray(value);
88622
+ }
88623
+ var init_project_version_relation_sweep_trigger = __esm({
88624
+ "../src/database/project-version-relation-sweep-trigger.ts"() {
88625
+ "use strict";
88626
+ }
88627
+ });
88628
+
88567
88629
  // ../src/database/project-version-transaction-planning.ts
88568
88630
  function variantRootValueId2(data) {
88569
88631
  if (typeof data !== "object" || data === null) return null;
@@ -88585,7 +88647,7 @@ function addProjectVersionTransactionBudgets(left, right) {
88585
88647
  returnBytes: left.returnBytes + right.returnBytes
88586
88648
  };
88587
88649
  }
88588
- var KIB, MIB, PROJECT_TRANSACTION_CHUNK_PAYLOAD_TARGET_BYTES, PROJECT_TRANSACTION_IMMEDIATE_BUDGET, PROJECT_TRANSACTION_WORKER_BUDGET, PROJECT_TRANSACTION_SINGLE_CHANGE_NATIVE_BUDGET, EMPTY_BUDGET, CHUNK_GRAPH_VALIDATION_RESERVE, CHUNK_FIXED_COST, IMMEDIATE_FIXED_COST, WHOLE_GRAPH_VALIDATION_SURCHARGE;
88650
+ var KIB, MIB, PROJECT_TRANSACTION_CHUNK_PAYLOAD_TARGET_BYTES, PROJECT_TRANSACTION_IMMEDIATE_BUDGET, PROJECT_TRANSACTION_WORKER_BUDGET, PROJECT_TRANSACTION_SINGLE_CHANGE_NATIVE_BUDGET, EMPTY_BUDGET, CHUNK_GRAPH_VALIDATION_RESERVE, CHUNK_FIXED_COST, IMMEDIATE_FIXED_COST, WHOLE_GRAPH_VALIDATION_SURCHARGE, CHANGE_BYTES_READ_OVERHEAD, CHANGE_BYTES_WRITTEN_OVERHEAD;
88589
88651
  var init_project_version_transaction_planning = __esm({
88590
88652
  "../src/database/project-version-transaction-planning.ts"() {
88591
88653
  "use strict";
@@ -88599,8 +88661,8 @@ var init_project_version_transaction_planning = __esm({
88599
88661
  bytesWritten: 4 * MIB,
88600
88662
  documentsRead: 4e3,
88601
88663
  documentsWritten: 1400,
88602
- databaseQueries: 420,
88603
- indexRanges: 320,
88664
+ databaseQueries: 800,
88665
+ indexRanges: 800,
88604
88666
  functionsScheduled: 24,
88605
88667
  scheduledFunctionArgsBytes: 64 * KIB,
88606
88668
  returnBytes: 4 * MIB
@@ -88611,8 +88673,8 @@ var init_project_version_transaction_planning = __esm({
88611
88673
  bytesWritten: 4 * MIB,
88612
88674
  documentsRead: 4e3,
88613
88675
  documentsWritten: 900,
88614
- databaseQueries: 420,
88615
- indexRanges: 320,
88676
+ databaseQueries: 700,
88677
+ indexRanges: 700,
88616
88678
  functionsScheduled: 8,
88617
88679
  scheduledFunctionArgsBytes: 32 * KIB,
88618
88680
  returnBytes: 128 * KIB
@@ -88648,9 +88710,9 @@ var init_project_version_transaction_planning = __esm({
88648
88710
  bytesRead: 32 * KIB,
88649
88711
  bytesWritten: 48 * KIB,
88650
88712
  documentsRead: 4,
88651
- documentsWritten: 4,
88652
- databaseQueries: 10,
88653
- indexRanges: 8,
88713
+ documentsWritten: 5,
88714
+ databaseQueries: 97,
88715
+ indexRanges: 105,
88654
88716
  functionsScheduled: 2,
88655
88717
  scheduledFunctionArgsBytes: 2 * KIB,
88656
88718
  returnBytes: 2 * KIB
@@ -88659,21 +88721,23 @@ var init_project_version_transaction_planning = __esm({
88659
88721
  argumentBytes: 2 * KIB,
88660
88722
  bytesRead: 96 * KIB,
88661
88723
  bytesWritten: 64 * KIB,
88662
- documentsRead: 12,
88663
- documentsWritten: 4,
88724
+ documentsRead: 18,
88725
+ documentsWritten: 8,
88664
88726
  databaseQueries: 34,
88665
- indexRanges: 24,
88727
+ indexRanges: 34,
88666
88728
  functionsScheduled: 4,
88667
88729
  scheduledFunctionArgsBytes: 8 * KIB,
88668
88730
  returnBytes: 8 * KIB
88669
88731
  };
88670
88732
  WHOLE_GRAPH_VALIDATION_SURCHARGE = {
88671
88733
  ...EMPTY_BUDGET,
88672
- bytesRead: 512 * KIB,
88673
- documentsRead: 400,
88674
- databaseQueries: 300,
88675
- indexRanges: 200
88734
+ bytesRead: 336 * KIB,
88735
+ documentsRead: 782,
88736
+ databaseQueries: 410,
88737
+ indexRanges: 410
88676
88738
  };
88739
+ CHANGE_BYTES_READ_OVERHEAD = 4 * KIB;
88740
+ CHANGE_BYTES_WRITTEN_OVERHEAD = 4 * KIB;
88677
88741
  }
88678
88742
  });
88679
88743
 
@@ -90065,11 +90129,16 @@ function prepareServerOwnedSchemaCommit(args) {
90065
90129
  if (listIndexErrors.length > 0) {
90066
90130
  throw new Error(listIndexErrors[0].message);
90067
90131
  }
90068
- validateInternalRecordRelations({
90069
- relations: postDocument.internalRecordRelations ?? [],
90070
- endpoints: collectProjectDocumentRelationEndpoints(postDocument),
90071
- classes: postDocument.classes
90072
- });
90132
+ if (stagedChangesAffectClassRelations(args.document, [
90133
+ ...prepared,
90134
+ ...readOnlyConversionChanges
90135
+ ])) {
90136
+ validateInternalRecordRelations({
90137
+ relations: postDocument.internalRecordRelations ?? [],
90138
+ endpoints: collectProjectDocumentRelationEndpoints(postDocument),
90139
+ classes: postDocument.classes
90140
+ });
90141
+ }
90073
90142
  const accessModifierErrors = validateDocumentAccessModifiers({
90074
90143
  members: postDocument.members,
90075
90144
  classes: postDocument.classes,
@@ -90216,10 +90285,6 @@ function orderVariantRootValuesWithVariants(prepared) {
90216
90285
  return ordered;
90217
90286
  }
90218
90287
  function materializePreparedInstanceInitializers(args) {
90219
- const compiledDocument = applyProjectVersionWriteChanges(
90220
- args.document,
90221
- args.prepared
90222
- );
90223
90288
  const sites = /* @__PURE__ */ new Map();
90224
90289
  for (let index = 0; index < args.prepared.length; index += 1) {
90225
90290
  const change = args.prepared[index];
@@ -90234,6 +90299,10 @@ function materializePreparedInstanceInitializers(args) {
90234
90299
  });
90235
90300
  }
90236
90301
  if (sites.size === 0) return;
90302
+ const compiledDocument = applyProjectVersionWriteChanges(
90303
+ args.document,
90304
+ args.prepared
90305
+ );
90237
90306
  const existingValueById = new Map(
90238
90307
  args.document.values.map((value) => [value.id, value])
90239
90308
  );
@@ -91615,6 +91684,15 @@ function normalizeClientBindingMemberCreates(args) {
91615
91684
  };
91616
91685
  }
91617
91686
  }
91687
+ function stampsAbsentBindingMember(value, existingMemberIds) {
91688
+ const stamp = value.genericBindings;
91689
+ if (stamp === void 0 || stamp === null) return false;
91690
+ for (const bindingMemberId of Object.values(stamp)) {
91691
+ if (typeof bindingMemberId !== "string") continue;
91692
+ if (!existingMemberIds.has(bindingMemberId)) return true;
91693
+ }
91694
+ return false;
91695
+ }
91618
91696
  function materializeVariantChildOverrideBindingMembers(args) {
91619
91697
  normalizeClientBindingMemberCreates(args);
91620
91698
  const postDocument = applyProjectVersionWriteChanges(
@@ -91623,6 +91701,13 @@ function materializeVariantChildOverrideBindingMembers(args) {
91623
91701
  );
91624
91702
  const variants = postDocument.variants ?? [];
91625
91703
  if (variants.length === 0) return;
91704
+ const existingMemberIds = new Set(
91705
+ postDocument.members.map((member) => member.id)
91706
+ );
91707
+ const candidates = postDocument.values.filter(
91708
+ (value) => stampsAbsentBindingMember(value, existingMemberIds)
91709
+ );
91710
+ if (candidates.length === 0) return;
91626
91711
  const graphValueIds = collectVariantGraphValueIds({
91627
91712
  document: postDocument,
91628
91713
  variants,
@@ -91635,11 +91720,8 @@ function materializeVariantChildOverrideBindingMembers(args) {
91635
91720
  schemaClass2.id
91636
91721
  ])
91637
91722
  );
91638
- const existingMemberIds = new Set(
91639
- postDocument.members.map((member) => member.id)
91640
- );
91641
91723
  const minted = /* @__PURE__ */ new Set();
91642
- for (const value of postDocument.values) {
91724
+ for (const value of candidates) {
91643
91725
  if (!graphValueIds.has(value.id)) continue;
91644
91726
  const stamp = value.genericBindings;
91645
91727
  if (stamp === void 0 || stamp === null) continue;
@@ -93492,6 +93574,7 @@ var init_project_version_schema_commit = __esm({
93492
93574
  init_general_function_call_ir_source_recompile();
93493
93575
  init_projectDocumentDialogueMaterialization();
93494
93576
  init_project_version_transaction_types();
93577
+ init_project_version_relation_sweep_trigger();
93495
93578
  init_project_version_transaction_planning();
93496
93579
  init_project_version_static_value_writes();
93497
93580
  init_localizable_member_value_writes();
@@ -93532,7 +93615,7 @@ var init_project_version_schema_commit = __esm({
93532
93615
 
93533
93616
  // ../src/database/project-record-semantics.ts
93534
93617
  function projectRecordSemanticData(value) {
93535
- if (!isPlainRecord(value)) return value;
93618
+ if (!isPlainRecord2(value)) return value;
93536
93619
  const semantic = {};
93537
93620
  for (const [key, child] of Object.entries(value)) {
93538
93621
  if (SERVER_MANAGED_PROJECT_RECORD_FIELDS.has(key)) continue;
@@ -93569,7 +93652,7 @@ function toCanonicalJsonValue2(value) {
93569
93652
  if (Array.isArray(value)) {
93570
93653
  return value.map((item) => toCanonicalJsonValue2(item) ?? null);
93571
93654
  }
93572
- if (!isPlainRecord(value)) {
93655
+ if (!isPlainRecord2(value)) {
93573
93656
  throw new Error("Cannot canonicalize a non-plain object.");
93574
93657
  }
93575
93658
  const canonical = {};
@@ -93583,7 +93666,7 @@ function toCanonicalJsonValue2(value) {
93583
93666
  }
93584
93667
  return canonical;
93585
93668
  }
93586
- function isPlainRecord(value) {
93669
+ function isPlainRecord2(value) {
93587
93670
  if (value === null || typeof value !== "object") return false;
93588
93671
  const prototype = Object.getPrototypeOf(value);
93589
93672
  return prototype === Object.prototype || prototype === null;
@@ -93692,7 +93775,7 @@ function systemProtectedWriteInheritedRecordId(write) {
93692
93775
  if (write.baseData !== void 0) return null;
93693
93776
  if (write.deleted) return null;
93694
93777
  if (!isSystemBearingRecordKind(write.recordKind)) return null;
93695
- if (!isPlainRecord2(write.nextData)) return null;
93778
+ if (!isPlainRecord3(write.nextData)) return null;
93696
93779
  if (readSystemMetadata(write.nextData) === null) return null;
93697
93780
  const extendsMemberId = write.nextData.extendsMemberId;
93698
93781
  if (typeof extendsMemberId !== "string") return null;
@@ -93712,7 +93795,7 @@ function assertSystemProtectedRecordWriteValid(write) {
93712
93795
  assertSystemMetadataUnchanged(write, base);
93713
93796
  }
93714
93797
  function readBaseRecord(write) {
93715
- if (!isPlainRecord2(write.baseData)) return null;
93798
+ if (!isPlainRecord3(write.baseData)) return null;
93716
93799
  return {
93717
93800
  recordKind: write.recordKind,
93718
93801
  data: write.baseData,
@@ -93725,7 +93808,7 @@ function collectSystemBearingBaseRecords(document) {
93725
93808
  const stored = document[collection];
93726
93809
  if (!Array.isArray(stored)) continue;
93727
93810
  for (const record3 of stored) {
93728
- if (!isPlainRecord2(record3)) continue;
93811
+ if (!isPlainRecord3(record3)) continue;
93729
93812
  const id2 = record3.id;
93730
93813
  if (typeof id2 !== "string") continue;
93731
93814
  records2.set(baseKey(recordKind, id2), {
@@ -93739,7 +93822,7 @@ function collectSystemBearingBaseRecords(document) {
93739
93822
  }
93740
93823
  function assertCreateDeclaresNoSystemMetadata(write) {
93741
93824
  if (!isSystemBearingRecordKind(write.recordKind)) return;
93742
- if (!isPlainRecord2(write.nextData)) return;
93825
+ if (!isPlainRecord3(write.nextData)) return;
93743
93826
  const system = readSystemMetadata(write.nextData);
93744
93827
  if (system === null) return;
93745
93828
  if (inheritsLegacyEmittedSystemMetadata(write, system)) return;
@@ -93765,7 +93848,7 @@ function assertProtectedRecordNotEdited(change, base) {
93765
93848
  )) {
93766
93849
  return;
93767
93850
  }
93768
- if (!isPlainRecord2(change.nextData)) return;
93851
+ if (!isPlainRecord3(change.nextData)) return;
93769
93852
  if (authoredFieldsEqual(change.recordKind, base.data, change.nextData)) {
93770
93853
  return;
93771
93854
  }
@@ -93774,7 +93857,7 @@ function assertProtectedRecordNotEdited(change, base) {
93774
93857
  );
93775
93858
  }
93776
93859
  function assertSystemMetadataUnchanged(change, base) {
93777
- if (!isPlainRecord2(change.nextData)) return;
93860
+ if (!isPlainRecord3(change.nextData)) return;
93778
93861
  const next = readSystemMetadata(change.nextData);
93779
93862
  if (systemMetadataEqual(base.system, next)) return;
93780
93863
  throw new Error(
@@ -93822,10 +93905,10 @@ function repointedChildValueIds(document, change) {
93822
93905
  );
93823
93906
  if (baseValue === void 0) return [];
93824
93907
  const before = baseValue.value;
93825
- if (!isPlainRecord2(before)) return [];
93826
- if (!isPlainRecord2(change.nextData)) return [];
93908
+ if (!isPlainRecord3(before)) return [];
93909
+ if (!isPlainRecord3(change.nextData)) return [];
93827
93910
  const after = change.nextData.value;
93828
- if (!isPlainRecord2(after)) return [];
93911
+ if (!isPlainRecord3(after)) return [];
93829
93912
  return Object.entries(before).flatMap(([schemaKey, childValueId]) => {
93830
93913
  if (typeof childValueId !== "string") return [];
93831
93914
  if (after[schemaKey] === childValueId) return [];
@@ -93860,7 +93943,7 @@ function isSystemBearingRecordKind(recordKind) {
93860
93943
  );
93861
93944
  }
93862
93945
  function readSystemMetadata(record3) {
93863
- if (!isPlainRecord2(record3)) return null;
93946
+ if (!isPlainRecord3(record3)) return null;
93864
93947
  const system = record3.system;
93865
93948
  if (!isSystemMetadata(system)) return null;
93866
93949
  return system;
@@ -93879,11 +93962,11 @@ function systemReason(system) {
93879
93962
  return SYSTEM_PROTECTION_RULES[system.kind].serverReason;
93880
93963
  }
93881
93964
  function describeChangedRecord(recordKind, recordId, record3) {
93882
- const name = isPlainRecord2(record3) ? record3.name : void 0;
93965
+ const name = isPlainRecord3(record3) ? record3.name : void 0;
93883
93966
  if (typeof name !== "string") return `Record ${recordKind} "${recordId}"`;
93884
93967
  return `Record ${recordKind} "${name}" (${recordId})`;
93885
93968
  }
93886
- function isPlainRecord2(value) {
93969
+ function isPlainRecord3(value) {
93887
93970
  return typeof value === "object" && value !== null && !Array.isArray(value);
93888
93971
  }
93889
93972
  function baseKey(recordKind, recordId) {
@@ -93997,7 +94080,7 @@ function readWorldReferenceList(args) {
93997
94080
  args.keyCandidates
93998
94081
  );
93999
94082
  if (schemaKey === null) return [];
94000
- if (!isPlainRecord3(args.ownerValue.value)) return [];
94083
+ if (!isPlainRecord4(args.ownerValue.value)) return [];
94001
94084
  const listValueId = args.ownerValue.value[schemaKey];
94002
94085
  if (typeof listValueId !== "string") return [];
94003
94086
  const listValue2 = args.graph.valuesById.get(listValueId);
@@ -94063,18 +94146,18 @@ function worldReferenceClassInherits(graph, classId, ancestorClassId) {
94063
94146
  return false;
94064
94147
  }
94065
94148
  function toWorldReferenceClassRecord(value) {
94066
- if (!isPlainRecord3(value)) return null;
94149
+ if (!isPlainRecord4(value)) return null;
94067
94150
  const id2 = stringField2(value, "id");
94068
94151
  if (id2 === null) return null;
94069
94152
  return {
94070
94153
  id: id2,
94071
94154
  extendsClassId: nullableStringField(value, "extendsClassId"),
94072
94155
  schema: isStringRecord5(value.schema) ? value.schema : void 0,
94073
- system: isPlainRecord3(value.system) ? value.system : null
94156
+ system: isPlainRecord4(value.system) ? value.system : null
94074
94157
  };
94075
94158
  }
94076
94159
  function toWorldReferenceValueRecord(value) {
94077
- if (!isPlainRecord3(value)) return null;
94160
+ if (!isPlainRecord4(value)) return null;
94078
94161
  const id2 = stringField2(value, "id");
94079
94162
  if (id2 === null) return null;
94080
94163
  return {
@@ -94088,10 +94171,10 @@ function worldReferenceValueClassId(value) {
94088
94171
  return typeof value.classId === "string" && value.classId.length > 0 ? value.classId : null;
94089
94172
  }
94090
94173
  function isStringRecord5(value) {
94091
- if (!isPlainRecord3(value)) return false;
94174
+ if (!isPlainRecord4(value)) return false;
94092
94175
  return Object.values(value).every((entry) => typeof entry === "string");
94093
94176
  }
94094
- function isPlainRecord3(value) {
94177
+ function isPlainRecord4(value) {
94095
94178
  return typeof value === "object" && value !== null && !Array.isArray(value);
94096
94179
  }
94097
94180
  function stringField2(value, key) {
@@ -94390,31 +94473,6 @@ function assertStagedInternalRecordRelationsValid(current, projected, changes) {
94390
94473
  classes: projected.classes
94391
94474
  });
94392
94475
  }
94393
- function stagedChangesAffectClassRelations(current, changes) {
94394
- const classesById = new Map(
94395
- current.classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
94396
- );
94397
- const valuesById = new Map(current.values.map((value) => [value.id, value]));
94398
- for (const change of changes) {
94399
- if (change.recordKind === "internal-record-relation") return true;
94400
- if (change.recordKind === "class") {
94401
- if (change.operation !== "update") return true;
94402
- if (change.deleted === true) return true;
94403
- const before2 = classesById.get(change.recordId);
94404
- if (before2 === void 0) return true;
94405
- const after = change.nextData;
94406
- if (!isPlainRecord4(after)) return true;
94407
- if (before2.extendsClassId !== after.extendsClassId) return true;
94408
- continue;
94409
- }
94410
- if (change.recordKind !== "value") continue;
94411
- const before = valuesById.get(change.recordId);
94412
- if (relationEndpointClassId(before) !== relationEndpointClassId(change.nextData)) {
94413
- return true;
94414
- }
94415
- }
94416
- return false;
94417
- }
94418
94476
  function assertStagedWorldContentLayerBindingsValid(current, projected, changes) {
94419
94477
  if (!stagedChangesRequireWorldLayerBindingValidation(current, changes)) {
94420
94478
  return;
@@ -94461,7 +94519,7 @@ function stagedChangesRequireWorldLayerBindingValidation(current, changes) {
94461
94519
  const before = classesById.get(change.recordId);
94462
94520
  if (before === void 0) return true;
94463
94521
  const after = change.nextData;
94464
- if (!isPlainRecord4(after)) return true;
94522
+ if (!isPlainRecord(after)) return true;
94465
94523
  if (before.extendsClassId !== after.extendsClassId) return true;
94466
94524
  if (before.isAbstract !== after.isAbstract) return true;
94467
94525
  if (!worldClassSystemBlockIsEqual(before.system, after.system)) return true;
@@ -94512,7 +94570,7 @@ function stagedAffectedWorldLayerLinkClassIds(args) {
94512
94570
  change.nextData
94513
94571
  ];
94514
94572
  for (const candidate of candidates) {
94515
- if (!isPlainRecord4(candidate)) continue;
94573
+ if (!isPlainRecord(candidate)) continue;
94516
94574
  const relationKind = candidate.relationKind;
94517
94575
  if (typeof relationKind !== "string") continue;
94518
94576
  if (!isStagedWorldLayerLinkTargetRelationKind(relationKind)) continue;
@@ -94555,21 +94613,11 @@ function worldClassSystemBlockIsEqual(before, after) {
94555
94613
  );
94556
94614
  }
94557
94615
  function hasWorldLayerOverrideMetadata(record3) {
94558
- if (!isPlainRecord4(record3)) return false;
94616
+ if (!isPlainRecord(record3)) return false;
94559
94617
  const value = record3.value;
94560
- if (!isPlainRecord4(value)) return false;
94618
+ if (!isPlainRecord(value)) return false;
94561
94619
  return typeof value.layerOverrideValueId === "string";
94562
94620
  }
94563
- function relationEndpointClassId(record3) {
94564
- if (!isPlainRecord4(record3)) return void 0;
94565
- if (typeof record3.classId === "string") return record3.classId;
94566
- if (typeof record3.typeId === "string") return record3.typeId;
94567
- return void 0;
94568
- }
94569
- function isPlainRecord4(value) {
94570
- if (value === null || typeof value !== "object") return false;
94571
- return !Array.isArray(value);
94572
- }
94573
94621
  function assertStagedProjectInterfaceValid(projected, changes) {
94574
94622
  const relevant = changes.filter(
94575
94623
  (change) => INTERFACE_VALIDATED_RECORD_KINDS.has(change.recordKind)
@@ -94703,7 +94751,7 @@ function candidateActionListenerRowIds(projected, actions) {
94703
94751
  }
94704
94752
  if (actionSchemaKeys.size === 0) return candidates;
94705
94753
  for (const row of projected.values) {
94706
- if (!isPlainRecord4(row.value)) continue;
94754
+ if (!isPlainRecord(row.value)) continue;
94707
94755
  for (const schemaKey of actionSchemaKeys) {
94708
94756
  const childId = row.value[schemaKey];
94709
94757
  if (typeof childId === "string") candidates.add(childId);
@@ -94713,7 +94761,7 @@ function candidateActionListenerRowIds(projected, actions) {
94713
94761
  }
94714
94762
  function storedRowActionListeners(row) {
94715
94763
  const body = row.value;
94716
- if (!isPlainRecord4(body)) return [];
94764
+ if (!isPlainRecord(body)) return [];
94717
94765
  const listeners = body.listeners;
94718
94766
  return Array.isArray(listeners) ? listeners : [];
94719
94767
  }
@@ -94791,7 +94839,7 @@ function authoredActionListeners(action) {
94791
94839
  if (defaultValue === void 0 || defaultValue === null) return [];
94792
94840
  if (!isLiteralValueContent(defaultValue)) return [];
94793
94841
  const body = defaultValue.value;
94794
- if (!isPlainRecord4(body)) return [];
94842
+ if (!isPlainRecord(body)) return [];
94795
94843
  const listeners = body.listeners;
94796
94844
  return Array.isArray(listeners) ? listeners : [];
94797
94845
  }
@@ -95131,7 +95179,7 @@ function candidateVariantRowIds(projected, variantMembers) {
95131
95179
  }
95132
95180
  if (schemaKeys.size === 0) return candidates;
95133
95181
  for (const row of projected.values) {
95134
- if (!isPlainRecord4(row.value)) continue;
95182
+ if (!isPlainRecord(row.value)) continue;
95135
95183
  for (const schemaKey of schemaKeys) {
95136
95184
  const childId = row.value[schemaKey];
95137
95185
  if (typeof childId === "string") candidates.add(childId);
@@ -95168,6 +95216,7 @@ var init_project_version_whole_graph_validation = __esm({
95168
95216
  init_world_system_classes();
95169
95217
  init_project_world_reference_graph();
95170
95218
  init_project_record_semantics();
95219
+ init_project_version_relation_sweep_trigger();
95171
95220
  INTERFACE_VALIDATED_RECORD_KINDS = /* @__PURE__ */ new Set([
95172
95221
  "member",
95173
95222
  "class",
@@ -112040,10 +112089,20 @@ async function downloadProjectVersionTransactionResult(args) {
112040
112089
  }
112041
112090
  changedRecords.push(...page.changedRecords);
112042
112091
  if (page.isDone) {
112092
+ if (args.status.totalChangeCount === null) {
112093
+ throw new Error(
112094
+ `Project transaction "${args.transactionId}" reported no total change count after committing; its result download cannot be checked for completeness.`
112095
+ );
112096
+ }
112097
+ if (changedRecords.length !== args.status.totalChangeCount) {
112098
+ throw new Error(
112099
+ `Project transaction "${args.transactionId}" committed ${args.status.totalChangeCount} changes but its result download returned ${changedRecords.length}.`
112100
+ );
112101
+ }
112043
112102
  return {
112044
112103
  kind: "committed",
112045
112104
  transactionId: args.transactionId,
112046
- totalChangeCount: args.status.totalChangeCount ?? changedRecords.length,
112105
+ totalChangeCount: args.status.totalChangeCount,
112047
112106
  totalChunkCount: args.status.totalChunkCount ?? 0,
112048
112107
  assignments,
112049
112108
  changedRecords
@@ -114336,7 +114395,7 @@ var init_registry2 = __esm({
114336
114395
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
114337
114396
  formatVersion: 3,
114338
114397
  contractVersion: "3.14",
114339
- cliVersion: "0.36.9",
114398
+ cliVersion: "0.36.10",
114340
114399
  projectFileUploadBatchSize: 32,
114341
114400
  documentRecords: {
114342
114401
  member: {
@@ -120652,7 +120711,7 @@ __export(resolve_exports, {
120652
120711
  import { readFileSync as readFileSync19, rmSync as rmSync8, writeFileSync as writeFileSync14 } from "node:fs";
120653
120712
  import { join as join21 } from "node:path";
120654
120713
  function runResolve(workspace, side) {
120655
- const resolvedRecords = acceptSourceEquivalentConflictBases(workspace);
120714
+ const resolvedRecords = adoptServerConflictBases(workspace);
120656
120715
  let resolvedFiles = 0;
120657
120716
  for (const filePath of listProjectSourceFilesV4(workspace.root)) {
120658
120717
  const source = readFileSync19(filePath, "utf8");
@@ -120697,6 +120756,22 @@ function runResolve(workspace, side) {
120697
120756
  `Resolved ${resolvedFiles} source file(s), ${resolvedRecords} record conflict(s), and ${resolvedBinaries} binary file(s) keeping the "${side}" side. Review with "neo diff", then "neo push".`
120698
120757
  );
120699
120758
  }
120759
+ function adoptServerConflictBases(workspace) {
120760
+ let adopted = 0;
120761
+ for (const [key, record3] of Object.entries(workspace.state.records)) {
120762
+ if (typeof record3.conflictServerHash !== "string") continue;
120763
+ const next = {
120764
+ ...record3,
120765
+ contentHash: record3.conflictServerHash,
120766
+ data: record3.conflictServerData
120767
+ };
120768
+ delete next.conflictServerHash;
120769
+ delete next.conflictServerData;
120770
+ workspace.state.records[key] = next;
120771
+ adopted += 1;
120772
+ }
120773
+ return adopted;
120774
+ }
120700
120775
  function resolveMarkers(source, side) {
120701
120776
  const lines = source.split("\n");
120702
120777
  const output = [];
@@ -120743,7 +120818,6 @@ var init_resolve = __esm({
120743
120818
  init_workspace_status();
120744
120819
  init_source_diagnostics();
120745
120820
  init_project_files();
120746
- init_source_record_comparison();
120747
120821
  }
120748
120822
  });
120749
120823
 
@@ -120940,7 +121014,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
120940
121014
  async function main() {
120941
121015
  const args = parseArgs(process.argv.slice(2));
120942
121016
  if (args.command === "--version") {
120943
- console.log("0.36.9");
121017
+ console.log("0.36.10");
120944
121018
  return;
120945
121019
  }
120946
121020
  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.36.9",
3
+ "version": "0.36.10",
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.36.9 -->
12
+ <!-- reviewed-through-cli: 0.36.10 -->
13
13
 
14
14
  # Neo Compose CLI
15
15
 
@@ -83,7 +83,7 @@ wrappers.
83
83
  The marker near the top of `SKILL.md` must exactly match the package version:
84
84
 
85
85
  ```html
86
- <!-- reviewed-through-cli: 0.36.9 -->
86
+ <!-- reviewed-through-cli: 0.36.10 -->
87
87
  ```
88
88
 
89
89
  The quoted version above is checked too, so this instruction cannot go stale