@neocompose/cli 0.27.0 → 0.27.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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.27.1] - 2026-08-12
4
+
5
+ ### Fixed
6
+
7
+ - Treat member-level `required` as non-semantic for Function and NSFunction
8
+ records during CLI reads and comparisons. Historical records stored with
9
+ `required: true` no longer produce permanent phantom changes in `neo pull`,
10
+ `neo status`, or `neo push --dry-run`; return nullability remains represented
11
+ by `returnTypeInfo.required`.
12
+ - Preserve independently mergeable edits on both sides of a `neo pull`
13
+ conflict marker, including nested fields and stable-ID collection entries.
14
+ Resolving with `neo resolve --mine` or `--theirs` now discards only genuinely
15
+ contested values instead of clean changes made on the other side.
16
+
3
17
  ## [0.27.0] - 2026-08-10
4
18
 
5
19
  ### Added
package/dist/neo.mjs CHANGED
@@ -12890,13 +12890,13 @@ var init_strict_resolver = __esm({
12890
12890
  scope,
12891
12891
  pos
12892
12892
  );
12893
- const selected2 = intrinsic(
12893
+ const selected = intrinsic(
12894
12894
  "select" /* Select */,
12895
12895
  { collectionPointer: receiver.pointer, function: fn },
12896
12896
  { kind: "list", elementType: resultType, readOnly: true }
12897
12897
  );
12898
12898
  return {
12899
- ...selected2,
12899
+ ...selected,
12900
12900
  entryWritability: inferredReturn.writability,
12901
12901
  writeRoot: inferredReturn.writeRoot
12902
12902
  };
@@ -25851,9 +25851,9 @@ function declaredConstructorNamedArguments(analysis, typeName, used) {
25851
25851
  )
25852
25852
  )
25853
25853
  );
25854
- const selected2 = reachable.length > 0 ? reachable : contract.constructors;
25854
+ const selected = reachable.length > 0 ? reachable : contract.constructors;
25855
25855
  const fields = /* @__PURE__ */ new Map();
25856
- for (const constructor2 of selected2) {
25856
+ for (const constructor2 of selected) {
25857
25857
  for (const parameter4 of constructor2.parameters) {
25858
25858
  if (fields.has(parameter4.name)) continue;
25859
25859
  fields.set(parameter4.name, parameterArgumentField(parameter4));
@@ -29499,14 +29499,14 @@ function sourceLocation(value, environment, field) {
29499
29499
  }
29500
29500
  function spanAndSelectionLocations(spanValue, selectionValue, environment, field) {
29501
29501
  const navigation = spanLocation(spanValue, environment, field);
29502
- const selection = spanLocation(
29502
+ const selection2 = spanLocation(
29503
29503
  selectionValue,
29504
29504
  environment,
29505
29505
  `${field}.selection`
29506
29506
  );
29507
29507
  return {
29508
29508
  ...navigation,
29509
- ...selection.location ? { selectionLocation: selection.location } : {}
29509
+ ...selection2.location ? { selectionLocation: selection2.location } : {}
29510
29510
  };
29511
29511
  }
29512
29512
  function scriptDefinitionLocations(member, environment, field) {
@@ -31222,6 +31222,9 @@ function normalizeDocumentFields(recordKind, value) {
31222
31222
  if (current === void 0) normalized[field] = null;
31223
31223
  }
31224
31224
  if (recordKind === "member") {
31225
+ if (CALLABLE_MEMBER_KINDS.has(normalized.kind)) {
31226
+ normalized.required = false;
31227
+ }
31225
31228
  normalizeTypeInfoBindings(normalized.returnTypeInfo);
31226
31229
  if (Array.isArray(normalized.argumentTypes)) {
31227
31230
  for (const argument2 of normalized.argumentTypes) {
@@ -31333,13 +31336,14 @@ function deepNormalizeValue(value) {
31333
31336
  function isRecord(value) {
31334
31337
  return typeof value === "object" && value !== null && !Array.isArray(value);
31335
31338
  }
31336
- var SchemaDocumentContractError;
31339
+ var CALLABLE_MEMBER_KINDS, SchemaDocumentContractError;
31337
31340
  var init_contracts = __esm({
31338
31341
  "src/project-manifest/contracts.ts"() {
31339
31342
  "use strict";
31340
31343
  init_document_contracts();
31341
31344
  init_machine_strings();
31342
31345
  init_document_contracts();
31346
+ CALLABLE_MEMBER_KINDS = /* @__PURE__ */ new Set([13, 23]);
31343
31347
  SchemaDocumentContractError = class extends Error {
31344
31348
  constructor(recordKind, field) {
31345
31349
  super(
@@ -31365,6 +31369,8 @@ function threeWayMergeRecord(base, server, local, policy = {}) {
31365
31369
  const comparisonServer = policy.comparison?.server ?? serverRecord;
31366
31370
  const comparisonLocal = policy.comparison?.local ?? localRecord;
31367
31371
  const merged = {};
31372
+ const localVariant = {};
31373
+ const serverVariant = {};
31368
31374
  const conflictFields = [];
31369
31375
  const keys = /* @__PURE__ */ new Set([
31370
31376
  ...Object.keys(serverRecord),
@@ -31375,7 +31381,11 @@ function threeWayMergeRecord(base, server, local, policy = {}) {
31375
31381
  const rawServerValue = serverRecord[key];
31376
31382
  const rawLocalValue = localRecord[key];
31377
31383
  if (policy.serverWinsFields?.has(key) === true) {
31378
- if (rawServerValue !== void 0) merged[key] = rawServerValue;
31384
+ if (rawServerValue !== void 0) {
31385
+ merged[key] = rawServerValue;
31386
+ localVariant[key] = rawServerValue;
31387
+ serverVariant[key] = rawServerValue;
31388
+ }
31379
31389
  continue;
31380
31390
  }
31381
31391
  const baseValue = comparisonBase[key];
@@ -31396,25 +31406,31 @@ function threeWayMergeRecord(base, server, local, policy = {}) {
31396
31406
  } else if (result.present) {
31397
31407
  merged[key] = result.value;
31398
31408
  }
31409
+ if (result.local.present) localVariant[key] = result.local.value;
31410
+ if (result.server.present) serverVariant[key] = result.server.value;
31399
31411
  }
31400
- return { merged, conflictFields };
31412
+ return { merged, localVariant, serverVariant, conflictFields };
31401
31413
  }
31402
31414
  function mergeValue(args) {
31403
31415
  if (canonicallyEqual(args.server, args.base)) {
31404
- return selected(args.rawLocal);
31416
+ return sharedSelection(args.rawLocal);
31405
31417
  }
31406
31418
  if (canonicallyEqual(args.local, args.base)) {
31407
- return selected(args.rawServer);
31419
+ return sharedSelection(args.rawServer);
31408
31420
  }
31409
31421
  if (canonicallyEqual(args.local, args.server)) {
31410
- return selected(args.rawLocal);
31422
+ return sharedSelection(args.rawLocal);
31423
+ }
31424
+ if (!args.recursive) {
31425
+ return conflict(args.path, args.rawLocal, args.rawServer);
31411
31426
  }
31412
- if (!args.recursive) return conflict(args.path);
31413
31427
  if (isObjectRecord2(args.rawBase) && isObjectRecord2(args.rawServer) && isObjectRecord2(args.rawLocal)) {
31414
31428
  const comparisonBase = isObjectRecord2(args.base) ? args.base : args.rawBase;
31415
31429
  const comparisonServer = isObjectRecord2(args.server) ? args.server : args.rawServer;
31416
31430
  const comparisonLocal = isObjectRecord2(args.local) ? args.local : args.rawLocal;
31417
31431
  const value = {};
31432
+ const localVariant = {};
31433
+ const serverVariant = {};
31418
31434
  const conflicts = [];
31419
31435
  const keys = /* @__PURE__ */ new Set([
31420
31436
  ...Object.keys(args.rawBase),
@@ -31434,8 +31450,16 @@ function mergeValue(args) {
31434
31450
  });
31435
31451
  conflicts.push(...nested.conflicts);
31436
31452
  if (nested.present) value[key] = nested.value;
31453
+ if (nested.local.present) localVariant[key] = nested.local.value;
31454
+ if (nested.server.present) serverVariant[key] = nested.server.value;
31437
31455
  }
31438
- return { present: true, value, conflicts };
31456
+ return {
31457
+ present: true,
31458
+ value,
31459
+ local: { present: true, value: localVariant },
31460
+ server: { present: true, value: serverVariant },
31461
+ conflicts
31462
+ };
31439
31463
  }
31440
31464
  if (Array.isArray(args.rawBase) && Array.isArray(args.rawServer) && Array.isArray(args.rawLocal)) {
31441
31465
  return mergeIdentityArray(
@@ -31445,17 +31469,24 @@ function mergeValue(args) {
31445
31469
  args.path
31446
31470
  );
31447
31471
  }
31448
- return conflict(args.path);
31472
+ return conflict(args.path, args.rawLocal, args.rawServer);
31449
31473
  }
31450
31474
  function mergeIdentityArray(base, server, local, path) {
31451
31475
  const baseItems = indexIdentityArray(base);
31452
31476
  const serverItems = indexIdentityArray(server);
31453
31477
  const localItems = indexIdentityArray(local);
31454
31478
  if (baseItems === null || serverItems === null || localItems === null) {
31455
- return conflict(path);
31479
+ return conflict(path, local, server);
31456
31480
  }
31457
- const retained = /* @__PURE__ */ new Map();
31481
+ const mergedValues = /* @__PURE__ */ new Map();
31482
+ const localValues = /* @__PURE__ */ new Map();
31483
+ const serverValues = /* @__PURE__ */ new Map();
31458
31484
  const conflicts = [];
31485
+ const retainShared = (id2, value2) => {
31486
+ mergedValues.set(id2, value2);
31487
+ localValues.set(id2, value2);
31488
+ serverValues.set(id2, value2);
31489
+ };
31459
31490
  const ids = /* @__PURE__ */ new Set([
31460
31491
  ...baseItems.order,
31461
31492
  ...serverItems.order,
@@ -31471,46 +31502,79 @@ function mergeIdentityArray(base, server, local, path) {
31471
31502
  if (baseHas && !serverHas && !localHas) continue;
31472
31503
  if (baseHas && !serverHas) {
31473
31504
  if (canonicallyEqual(localValue, baseValue)) continue;
31474
- conflicts.push(`${path}[${JSON.stringify(id2)}]`);
31505
+ conflicts.push(path + "[" + JSON.stringify(id2) + "]");
31506
+ localValues.set(id2, localValue);
31475
31507
  continue;
31476
31508
  }
31477
31509
  if (baseHas && !localHas) {
31478
31510
  if (canonicallyEqual(serverValue, baseValue)) continue;
31479
- conflicts.push(`${path}[${JSON.stringify(id2)}]`);
31511
+ conflicts.push(path + "[" + JSON.stringify(id2) + "]");
31512
+ serverValues.set(id2, serverValue);
31480
31513
  continue;
31481
31514
  }
31482
31515
  if (!serverHas && localHas) {
31483
- retained.set(id2, localValue);
31516
+ retainShared(id2, localValue);
31484
31517
  continue;
31485
31518
  }
31486
31519
  if (!localHas && serverHas) {
31487
- retained.set(id2, serverValue);
31520
+ retainShared(id2, serverValue);
31488
31521
  continue;
31489
31522
  }
31490
- const merged = mergeValue({
31523
+ const item = mergeValue({
31491
31524
  rawBase: baseValue,
31492
31525
  rawServer: serverValue,
31493
31526
  rawLocal: localValue,
31494
31527
  base: baseValue,
31495
31528
  server: serverValue,
31496
31529
  local: localValue,
31497
- path: `${path}[${JSON.stringify(id2)}]`,
31530
+ path: path + "[" + JSON.stringify(id2) + "]",
31498
31531
  recursive: true
31499
31532
  });
31500
- conflicts.push(...merged.conflicts);
31501
- if (merged.present) retained.set(id2, merged.value);
31533
+ conflicts.push(...item.conflicts);
31534
+ if (item.present) mergedValues.set(id2, item.value);
31535
+ if (item.local.present) localValues.set(id2, item.local.value);
31536
+ if (item.server.present) serverValues.set(id2, item.server.value);
31502
31537
  }
31503
- if (conflicts.length > 0) return { present: true, value: [], conflicts };
31504
- const order = mergeIdentityOrder(
31538
+ const retainedIds = /* @__PURE__ */ new Set([...localValues.keys(), ...serverValues.keys()]);
31539
+ const sharedOrder = mergeIdentityOrder(
31505
31540
  baseItems.order,
31506
31541
  serverItems.order,
31507
31542
  localItems.order,
31508
- new Set(retained.keys())
31543
+ retainedIds
31544
+ );
31545
+ if (sharedOrder === null) conflicts.push(path + ".$order");
31546
+ const localOrder = sharedOrder?.filter((id2) => localValues.has(id2)) ?? completeVariantOrder(
31547
+ localItems.order,
31548
+ serverItems.order,
31549
+ baseItems.order,
31550
+ new Set(localValues.keys())
31509
31551
  );
31510
- if (order === null) return conflict(`${path}.$order`);
31552
+ const serverOrder = sharedOrder?.filter((id2) => serverValues.has(id2)) ?? completeVariantOrder(
31553
+ serverItems.order,
31554
+ localItems.order,
31555
+ baseItems.order,
31556
+ new Set(serverValues.keys())
31557
+ );
31558
+ const localVariant = localOrder.map((id2) => localValues.get(id2));
31559
+ const serverVariant = serverOrder.map((id2) => serverValues.get(id2));
31560
+ if (conflicts.length > 0) {
31561
+ return {
31562
+ present: true,
31563
+ value: [],
31564
+ local: { present: true, value: localVariant },
31565
+ server: { present: true, value: serverVariant },
31566
+ conflicts
31567
+ };
31568
+ }
31569
+ if (sharedOrder === null) {
31570
+ throw new Error("A conflict-free identity merge must have a shared order.");
31571
+ }
31572
+ const value = sharedOrder.map((id2) => mergedValues.get(id2));
31511
31573
  return {
31512
31574
  present: true,
31513
- value: order.map((id2) => retained.get(id2)),
31575
+ value,
31576
+ local: { present: true, value },
31577
+ server: { present: true, value },
31514
31578
  conflicts: []
31515
31579
  };
31516
31580
  }
@@ -31567,11 +31631,51 @@ function mergeIdentityOrder(base, server, local, retained) {
31567
31631
  }
31568
31632
  return result.length === nodes.length ? result : null;
31569
31633
  }
31570
- function selected(value) {
31571
- return value === void 0 ? { present: false, conflicts: [] } : { present: true, value, conflicts: [] };
31634
+ function completeVariantOrder(preferred, fallback, base, retained) {
31635
+ const result = preferred.filter((id2) => retained.has(id2));
31636
+ const included = new Set(result);
31637
+ for (const source of [fallback, base]) {
31638
+ for (let index = 0; index < source.length; index += 1) {
31639
+ const id2 = source[index];
31640
+ if (!retained.has(id2) || included.has(id2)) continue;
31641
+ let insertionIndex = -1;
31642
+ for (let next = index + 1; next < source.length; next += 1) {
31643
+ const nextIndex = result.indexOf(source[next]);
31644
+ if (nextIndex !== -1) {
31645
+ insertionIndex = nextIndex;
31646
+ break;
31647
+ }
31648
+ }
31649
+ if (insertionIndex === -1) {
31650
+ for (let previous = index - 1; previous >= 0; previous -= 1) {
31651
+ const previousIndex = result.indexOf(source[previous]);
31652
+ if (previousIndex !== -1) {
31653
+ insertionIndex = previousIndex + 1;
31654
+ break;
31655
+ }
31656
+ }
31657
+ }
31658
+ if (insertionIndex === -1) insertionIndex = result.length;
31659
+ result.splice(insertionIndex, 0, id2);
31660
+ included.add(id2);
31661
+ }
31662
+ }
31663
+ return result;
31664
+ }
31665
+ function selection(value) {
31666
+ return value === void 0 ? { present: false } : { present: true, value };
31572
31667
  }
31573
- function conflict(path) {
31574
- return { present: false, conflicts: [path] };
31668
+ function sharedSelection(value) {
31669
+ const selected = selection(value);
31670
+ return { ...selected, local: selected, server: selected, conflicts: [] };
31671
+ }
31672
+ function conflict(path, localValue, serverValue) {
31673
+ return {
31674
+ present: false,
31675
+ local: selection(localValue),
31676
+ server: selection(serverValue),
31677
+ conflicts: [path]
31678
+ };
31575
31679
  }
31576
31680
  var init_merge = __esm({
31577
31681
  "src/project-sync/merge.ts"() {
@@ -51702,13 +51806,13 @@ function sourceBaseParameterNames(context, baseName, suppliedNames) {
51702
51806
  return required2.parameters.map((parameter4) => parameter4.name);
51703
51807
  }
51704
51808
  const declared = context.declaredConstructors.byClassName.get(baseName) ?? [];
51705
- const selected2 = selectOverload(
51809
+ const selected = selectOverload(
51706
51810
  declared.map(
51707
51811
  (constructor2) => constructor2.parameters.map((parameter4) => parameter4.name)
51708
51812
  ),
51709
51813
  suppliedNames
51710
51814
  );
51711
- return selected2;
51815
+ return selected;
51712
51816
  }
51713
51817
  function recordBaseParameterNames(context, baseName, suppliedNames) {
51714
51818
  const baseClassId = context.classIdsByName.get(baseName);
@@ -64639,7 +64743,7 @@ function evaluateInitializerInContext(init, member, ctx, createdValues, argument
64639
64743
  };
64640
64744
  }
64641
64745
  function encodeLookupInitializerResult(member, value, created, ctx) {
64642
- const selection = encodeLookupInitializerSelection(
64746
+ const selection2 = encodeLookupInitializerSelection(
64643
64747
  member,
64644
64748
  value,
64645
64749
  created,
@@ -64651,7 +64755,7 @@ function encodeLookupInitializerResult(member, value, created, ctx) {
64651
64755
  ctx.__executionState?.constructorGroups.delete(row.id);
64652
64756
  }
64653
64757
  }
64654
- return { value: selection, classId: null };
64758
+ return { value: selection2, classId: null };
64655
64759
  }
64656
64760
  function encodeLookupInitializerSelection(member, value, created, ctx) {
64657
64761
  if (value === null) return null;
@@ -72583,7 +72687,7 @@ var init_animation_clips = __esm({
72583
72687
  const seenChildren = /* @__PURE__ */ new Set();
72584
72688
  for (const row of rows) {
72585
72689
  const rowClassId = this.requireNodeClassId(row, "animationChildOverride");
72586
- const selected2 = this.resolveSelector(
72690
+ const selected = this.resolveSelector(
72587
72691
  row,
72588
72692
  rowClassId,
72589
72693
  WORLD_ANIMATION_CHILD_OVERRIDE_SELECTOR_MEMBER_ID,
@@ -72591,8 +72695,8 @@ var init_animation_clips = __esm({
72591
72695
  args.selectorOwnerNode,
72592
72696
  `Animation clip "${args.clipName}" frame ${args.frameIndex} child override`
72593
72697
  );
72594
- if (selected2 === null) continue;
72595
- const { childId, childClassId, childNode: child } = selected2;
72698
+ if (selected === null) continue;
72699
+ const { childId, childClassId, childNode: child } = selected;
72596
72700
  if (!args.childIds.has(childId)) {
72597
72701
  throw new Error(
72598
72702
  `Animation clip "${args.clipName}" frame ${args.frameIndex} references child "${childId}" outside the owner's authored Children graph.`
@@ -72758,7 +72862,7 @@ var init_animation_clips = __esm({
72758
72862
  * segment's length is instance data this document does not have.
72759
72863
  */
72760
72864
  validateTrackBase(args) {
72761
- const selected2 = this.resolveSelector(
72865
+ const selected = this.resolveSelector(
72762
72866
  args.track,
72763
72867
  args.trackClassId,
72764
72868
  WORLD_ANIMATION_TRACK_SELECTOR_MEMBER_ID,
@@ -72766,9 +72870,9 @@ var init_animation_clips = __esm({
72766
72870
  args.selectorOwnerNode,
72767
72871
  args.label
72768
72872
  );
72769
- if (selected2 !== null && !args.childIds.has(selected2.childId)) {
72873
+ if (selected !== null && !args.childIds.has(selected.childId)) {
72770
72874
  throw new Error(
72771
- `${args.label} references child "${selected2.childId}" outside the owner's authored Children graph.`
72875
+ `${args.label} references child "${selected.childId}" outside the owner's authored Children graph.`
72772
72876
  );
72773
72877
  }
72774
72878
  const startFrame = this.requireIntegerField(
@@ -72787,7 +72891,7 @@ var init_animation_clips = __esm({
72787
72891
  }
72788
72892
  this.validateTrackDirection(args.track, args.trackClassId, args.label);
72789
72893
  this.validateTrackCropWindow(args.track, args.trackClassId, args.label);
72790
- return selected2;
72894
+ return selected;
72791
72895
  }
72792
72896
  resolveSelector(parent, classId, selectorMemberId, refreshMemberId, _selectorOwnerNode, label) {
72793
72897
  this.validateSelectorRefresh(parent, classId, refreshMemberId, label);
@@ -74258,7 +74362,7 @@ function explicitTargetIds(changes) {
74258
74362
  return result;
74259
74363
  }
74260
74364
  function selectedRecordIds(records2, explicitIds, impactedIds, impactedTypeNames, constructedClassIds, impactedSourceNames, ownerId = () => null) {
74261
- const selected2 = new Set(explicitIds);
74365
+ const selected = new Set(explicitIds);
74262
74366
  for (const record3 of records2) {
74263
74367
  const owner = ownerId(record3);
74264
74368
  if (owner !== null && impactedIds.has(owner) || recordDependsOnChangedContract(
@@ -74268,10 +74372,10 @@ function selectedRecordIds(records2, explicitIds, impactedIds, impactedTypeNames
74268
74372
  constructedClassIds,
74269
74373
  impactedSourceNames
74270
74374
  )) {
74271
- selected2.add(record3.id);
74375
+ selected.add(record3.id);
74272
74376
  }
74273
74377
  }
74274
- return selected2;
74378
+ return selected;
74275
74379
  }
74276
74380
  function recordDependsOnChangedContract(record3, impactedIds, impactedTypeNames, constructedClassIds, impactedSourceNames) {
74277
74381
  const recordId = isObjectRecord3(record3) ? record3.id : void 0;
@@ -85325,11 +85429,11 @@ var init_project_version_whole_graph_validation = __esm({
85325
85429
 
85326
85430
  // src/project-source/workspace-status-core.ts
85327
85431
  function listVirtualProjectSourceFilesV4(files) {
85328
- const selected2 = files.filter((file) => {
85432
+ const selected = files.filter((file) => {
85329
85433
  const kind = neoProjectSourceKind(file.path);
85330
85434
  return kind !== null && isNeoProjectProductionSourceKind(kind) && !neoProjectPathHasIgnoredDirectory(file.path);
85331
85435
  });
85332
- const sorted = [...selected2].sort(
85436
+ const sorted = [...selected].sort(
85333
85437
  (left, right) => compareWorkspacePaths(left.path, right.path)
85334
85438
  );
85335
85439
  for (let index = 1; index < sorted.length; index += 1) {
@@ -91393,9 +91497,6 @@ function resolveLookupCollectionValueIds(context, member, collection, ownerValue
91393
91497
  member.collectionMemberId,
91394
91498
  collection.name
91395
91499
  );
91396
- if (declaredRows.size > 0) {
91397
- return { valueIds: [...declaredRows], origin: "collectionMember" };
91398
- }
91399
91500
  const candidates = /* @__PURE__ */ new Set();
91400
91501
  const collectionState = context.state[`member:${member.collectionMemberId}`];
91401
91502
  const collectionMemberData = isObjectRecord2(collectionState?.data) ? collectionState.data : {};
@@ -91407,6 +91508,12 @@ function resolveLookupCollectionValueIds(context, member, collection, ownerValue
91407
91508
  ) ?? []) {
91408
91509
  candidates.add(placedValueId);
91409
91510
  }
91511
+ if (declaredRows.size > 0) {
91512
+ return {
91513
+ valueIds: [.../* @__PURE__ */ new Set([...declaredRows, ...candidates])],
91514
+ origin: "collectionMember"
91515
+ };
91516
+ }
91410
91517
  return { valueIds: [...candidates], origin: "nameScan" };
91411
91518
  }
91412
91519
  function collectionRowsOfDeclaredMember(context, collectionMemberId, schemaKey) {
@@ -92369,13 +92476,13 @@ function storedValueConstructor(context, schemaClass2, constructorArgs) {
92369
92476
  `Stored construction for ${schemaClass2.name} cannot select one constructor from ${candidates.length} ${count}-argument candidates.`
92370
92477
  );
92371
92478
  }
92372
- const selected2 = candidates[0];
92373
- if (selected2 === void 0) {
92479
+ const selected = candidates[0];
92480
+ if (selected === void 0) {
92374
92481
  throw new Error(
92375
92482
  `Stored construction for ${schemaClass2.name} resolved no constructor.`
92376
92483
  );
92377
92484
  }
92378
- return selected2;
92485
+ return selected;
92379
92486
  }
92380
92487
  function storedConstructorArgumentSource(context, type, value, environment, visited, cloneAggregateArguments = false) {
92381
92488
  if (value === null) {
@@ -96073,7 +96180,7 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
96073
96180
  continue;
96074
96181
  }
96075
96182
  const localSide = locallyDeleted ? {} : local;
96076
- const { merged, conflictFields } = mergeProjectDocumentRecord(
96183
+ const { merged, localVariant, serverVariant, conflictFields } = mergeProjectDocumentRecord(
96077
96184
  serverRecord.recordKind,
96078
96185
  baseState.data,
96079
96186
  serverRecord.data,
@@ -96086,11 +96193,11 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
96086
96193
  plans.set(key, {
96087
96194
  // The working copy renders the LOCAL side; the marker's other half
96088
96195
  // comes from the server-variant emission.
96089
- emitData: locallyDeleted ? void 0 : localSide,
96196
+ emitData: locallyDeleted ? void 0 : localVariant,
96090
96197
  serverHash: serverRecord.contentHash,
96091
96198
  serverData: serverRecord.data,
96092
96199
  conflicted: true,
96093
- localData: locallyDeleted ? void 0 : localSide
96200
+ serverEmitData: locallyDeleted ? serverRecord.data : serverVariant
96094
96201
  });
96095
96202
  } else {
96096
96203
  mergedCount += 1;
@@ -96125,8 +96232,7 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
96125
96232
  emitData: local,
96126
96233
  serverHash: baseState.contentHash,
96127
96234
  serverData: void 0,
96128
- conflicted: true,
96129
- localData: local
96235
+ conflicted: true
96130
96236
  });
96131
96237
  continue;
96132
96238
  }
@@ -96621,7 +96727,7 @@ function sourceComparableObjectRecord(recordKind, value, mainLocale) {
96621
96727
  function buildEmitRecordSet(document, plans, side) {
96622
96728
  const records2 = /* @__PURE__ */ new Map();
96623
96729
  for (const [key, plan] of plans) {
96624
- const data = side === "emit" ? plan.emitData : plan.serverData;
96730
+ const data = side === "emit" ? plan.emitData : plan.serverEmitData ?? plan.serverData;
96625
96731
  if (data === void 0) continue;
96626
96732
  const serverRecord = document.records.get(key);
96627
96733
  const [recordKind, recordId] = key.split(/:(.+)/, 2);
@@ -103298,7 +103404,7 @@ var init_registry2 = __esm({
103298
103404
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
103299
103405
  formatVersion: 3,
103300
103406
  contractVersion: "3.9",
103301
- cliVersion: "0.27.0",
103407
+ cliVersion: "0.27.1",
103302
103408
  projectFileUploadBatchSize: 32,
103303
103409
  documentRecords: {
103304
103410
  member: {
@@ -105054,8 +105160,8 @@ function selectedSpecPaths(workspace, selectors) {
105054
105160
  const selectedPaths = all.filter((absolutePath) => {
105055
105161
  const path = relativePaths.get(absolutePath);
105056
105162
  const configured = configuredIncludes.length === 0 || configuredIncludes.some((pattern) => globMatches(pattern, path));
105057
- const selected2 = normalizedSelectors.length === 0 || normalizedSelectors.some((selector) => selectorMatches(selector, path));
105058
- return configured && selected2 && !(workspace.config.test?.exclude ?? []).some(
105163
+ const selected = normalizedSelectors.length === 0 || normalizedSelectors.some((selector) => selectorMatches(selector, path));
105164
+ return configured && selected && !(workspace.config.test?.exclude ?? []).some(
105059
105165
  (pattern) => globMatches(pattern.replaceAll("\\", "/"), path)
105060
105166
  );
105061
105167
  });
@@ -105256,22 +105362,22 @@ function registerSpec(spec, document) {
105256
105362
  );
105257
105363
  return { spec, root, tests };
105258
105364
  }
105259
- function mockResponse(environment, mock, selected2, call) {
105260
- if (selected2 === null) {
105365
+ function mockResponse(environment, mock, selected, call) {
105366
+ if (selected === null) {
105261
105367
  if (mock.callThrough) return { handled: false };
105262
105368
  throw new NeoTestAssertionError(
105263
105369
  `Mock for Function '${mock.memberId}' has no configured behavior. Add returns, throws, doesNothing, or implementation.`
105264
105370
  );
105265
105371
  }
105266
- if (selected2.kind === "throw") {
105267
- throw new NSGetterRuntimeError(selected2.message);
105372
+ if (selected.kind === "throw") {
105373
+ throw new NSGetterRuntimeError(selected.message);
105268
105374
  }
105269
- if (selected2.kind === "implementation") {
105375
+ if (selected.kind === "implementation") {
105270
105376
  return {
105271
105377
  handled: true,
105272
105378
  value: call.invokeDelegate(
105273
105379
  bindNeoScriptDelegateToContext(
105274
- selected2.delegate,
105380
+ selected.delegate,
105275
105381
  environment.context
105276
105382
  ),
105277
105383
  mock.isStatic ? call.args : [call.receiver, ...call.args]
@@ -105280,7 +105386,7 @@ function mockResponse(environment, mock, selected2, call) {
105280
105386
  }
105281
105387
  return {
105282
105388
  handled: true,
105283
- value: selected2.kind === "return" ? selected2.value : null
105389
+ value: selected.kind === "return" ? selected.value : null
105284
105390
  };
105285
105391
  }
105286
105392
  function partialObjectMatch(actual, expected) {
@@ -105297,16 +105403,16 @@ function matchingMock(environment, call) {
105297
105403
  (candidate) => candidate.receiverValueId !== void 0
105298
105404
  );
105299
105405
  const receiverValueId = needsReceiverLookup ? mockReceiverValueId(environment, call.receiver) : null;
105300
- let selected2;
105406
+ let selected;
105301
105407
  for (const candidate of candidates) {
105302
105408
  if (candidate.receiverValueId !== void 0 && candidate.receiverValueId !== receiverValueId) {
105303
105409
  continue;
105304
105410
  }
105305
- if (selected2 === void 0 || candidate.id > selected2.id) {
105306
- selected2 = candidate;
105411
+ if (selected === void 0 || candidate.id > selected.id) {
105412
+ selected = candidate;
105307
105413
  }
105308
105414
  }
105309
- return selected2;
105415
+ return selected;
105310
105416
  }
105311
105417
  function mockReceiverValueId(environment, receiver) {
105312
105418
  if (typeof receiver !== "object" || receiver === null) return null;
@@ -105651,15 +105757,15 @@ function failureFor(error, file, position, member = null) {
105651
105757
  ]
105652
105758
  };
105653
105759
  }
105654
- function suiteHasSelectedTests(suite, selected2) {
105655
- return suite.tests.some((test) => selected2.has(test.id)) || suite.suites.some((child) => suiteHasSelectedTests(child, selected2));
105760
+ function suiteHasSelectedTests(suite, selected) {
105761
+ return suite.tests.some((test) => selected.has(test.id)) || suite.suites.some((child) => suiteHasSelectedTests(child, selected));
105656
105762
  }
105657
- async function executeRegisteredSpec(registered, document, selected2, timeoutMs, interrupted) {
105763
+ async function executeRegisteredSpec(registered, document, selected, timeoutMs, interrupted) {
105658
105764
  const results = [];
105659
105765
  const fileFailures = [];
105660
105766
  let testDurationMs = 0;
105661
105767
  const executeSuite = async (suite, parentEnvironment, inheritedFailures) => {
105662
- if (!suiteHasSelectedTests(suite, selected2)) return;
105768
+ if (!suiteHasSelectedTests(suite, selected)) return;
105663
105769
  const fixture = cloneTestEnvironment(parentEnvironment);
105664
105770
  const suiteFailures = [...inheritedFailures];
105665
105771
  const suiteDeadline = Date.now() + timeoutMs;
@@ -105676,7 +105782,7 @@ async function executeRegisteredSpec(registered, document, selected2, timeoutMs,
105676
105782
  }
105677
105783
  }
105678
105784
  for (const test of suite.tests) {
105679
- if (!selected2.has(test.id)) continue;
105785
+ if (!selected.has(test.id)) continue;
105680
105786
  const started = performance.now();
105681
105787
  const deadline = Date.now() + timeoutMs;
105682
105788
  const environment = cloneTestEnvironment(fixture);
@@ -109864,7 +109970,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
109864
109970
  async function main() {
109865
109971
  const args = parseArgs(process.argv.slice(2));
109866
109972
  if (args.command === "--version") {
109867
- console.log("0.27.0");
109973
+ console.log("0.27.1");
109868
109974
  return;
109869
109975
  }
109870
109976
  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.27.0",
3
+ "version": "0.27.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.27.0 -->
12
+ <!-- reviewed-through-cli: 0.27.1 -->
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.27.0 -->
86
+ <!-- reviewed-through-cli: 0.27.1 -->
87
87
  ```
88
88
 
89
89
  The quoted version above is checked too, so this instruction cannot go stale