@neocompose/cli 0.9.1 → 0.9.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
@@ -7,6 +7,13 @@
7
7
  - Document the final relation-only world layer-link contract and keep the
8
8
  format-4 Hello World corpus free of the retired value-side binding field.
9
9
 
10
+ ## [0.9.2] - 2026-07-24
11
+
12
+ ### Fixed
13
+
14
+ - Create idless list entries inside existing stored value graphs, including
15
+ nested class subtrees and references to files created by the same push.
16
+
10
17
  ## [0.9.1] - 2026-07-24
11
18
 
12
19
  ### Fixed
package/dist/neo.mjs CHANGED
@@ -42084,6 +42084,7 @@ function lowerStaticValueSourcesV4(state, analysis, manifest) {
42084
42084
  );
42085
42085
  bindings.push({
42086
42086
  memberId,
42087
+ purpose: "stored",
42087
42088
  ownerClassId: sourceIdentityId(sourceClass, "class", sourceClass.name),
42088
42089
  initializer: declaration.initializer,
42089
42090
  source: declaration.source,
@@ -42125,12 +42126,14 @@ function buildValueLowerContext(state, manifest, options = {}) {
42125
42126
  ),
42126
42127
  staticValueIdsBySymbol: staticTargets,
42127
42128
  dialogueTargetsBySymbol: dialogueTargetsBySymbol(options.analysis),
42128
- projectFileIdsBySymbol: projectFileIdsBySymbol(state),
42129
+ projectFileIdsBySymbol: projectFileIdsBySymbol(state, options.analysis),
42129
42130
  mainLocale: projectMainLocaleFromState(state),
42130
42131
  valuePlacements: indexValuePlacements(state),
42131
42132
  parsedInitializers,
42132
42133
  reconstructed: /* @__PURE__ */ new Map(),
42133
42134
  pendingValues: /* @__PURE__ */ new Map(),
42135
+ pendingLocalizedTexts: /* @__PURE__ */ new Map(),
42136
+ loweredMemberIdByValueId: /* @__PURE__ */ new Map(),
42134
42137
  pendingBindingMembersByClassId: /* @__PURE__ */ new Map()
42135
42138
  };
42136
42139
  }
@@ -42167,6 +42170,7 @@ function lowerMemberDefaultSourcesV4(state, analysis, manifest) {
42167
42170
  if (member === void 0) continue;
42168
42171
  const binding = {
42169
42172
  memberId,
42173
+ purpose: "memberDefault",
42170
42174
  ownerClassId: sourceIdentityId(sourceClass, "class", sourceClass.name),
42171
42175
  initializer: declaration.initializer,
42172
42176
  source: declaration.source,
@@ -42380,13 +42384,75 @@ function lowerStoredBinding(context, binding, memberValueIds, seeds) {
42380
42384
  const valueId = annotatedId ?? currentValueId ?? pendingValueId(binding, binding.label);
42381
42385
  memberValueIds.set(binding.memberId, valueId);
42382
42386
  if (currentValueId === valueId) {
42387
+ const existingReconstructedKeys = new Set(context.reconstructed.keys());
42388
+ const existingPendingValueIds = new Set(context.pendingValues.keys());
42389
+ const existingPendingLocalizedTextIds = new Set(
42390
+ context.pendingLocalizedTexts.keys()
42391
+ );
42392
+ const existingPendingBindingMemberIds = new Set(
42393
+ [...context.pendingBindingMembersByClassId.values()].map(
42394
+ (pending) => pending.id
42395
+ )
42396
+ );
42383
42397
  lowerValueRow(context, member, expression, valueId, binding);
42398
+ const pendingRows = [...context.pendingValues.values()].filter(
42399
+ (row) => !existingPendingValueIds.has(row.id)
42400
+ );
42401
+ if (pendingRows.length > 0) {
42402
+ const root = reconstructedOrStateValue(context, valueId);
42403
+ const existingRows = [...context.reconstructed].filter(
42404
+ ([key, record3]) => key !== `value:${valueId}` && !existingReconstructedKeys.has(key) && record3.recordKind === "value"
42405
+ ).map(
42406
+ ([, record3]) => staticValueSeedRow(
42407
+ record3.fileFields,
42408
+ context.loweredMemberIdByValueId.get(record3.recordId)
42409
+ )
42410
+ );
42411
+ const bindingMembers = [
42412
+ ...context.pendingBindingMembersByClassId.values()
42413
+ ].filter((pending) => !existingPendingBindingMemberIds.has(pending.id));
42414
+ const localizedTexts = [...context.pendingLocalizedTexts.values()].filter(
42415
+ (text) => !existingPendingLocalizedTextIds.has(text.id)
42416
+ );
42417
+ seeds.set(binding.memberId, {
42418
+ value: root.value,
42419
+ classId: stringOrNull(root.classId),
42420
+ valueId,
42421
+ values: [...existingRows, ...pendingRows],
42422
+ ...bindingMembers.length === 0 ? {} : { bindingMembers },
42423
+ ...localizedTexts.length === 0 ? {} : { localizedTexts }
42424
+ });
42425
+ }
42384
42426
  return;
42385
42427
  }
42386
42428
  preserveReboundValue(context, currentValueId, valueId, binding);
42387
42429
  const seed = lowerStaticSeed(context, member, expression, binding, valueId);
42388
42430
  seeds.set(binding.memberId, { ...seed, valueId });
42389
42431
  }
42432
+ function reconstructedOrStateValue(context, valueId) {
42433
+ return context.reconstructed.get(`value:${valueId}`)?.fileFields ?? valueBase(context, valueId);
42434
+ }
42435
+ function staticValueSeedRow(value, loweredMemberId) {
42436
+ const id2 = stringOrNull(value.id);
42437
+ if (id2 === null) throw new Error("Authored value row is missing id.");
42438
+ if (loweredMemberId === void 0) {
42439
+ throw new Error(`Authored value row ${id2} is missing memberId.`);
42440
+ }
42441
+ return {
42442
+ id: id2,
42443
+ memberId: loweredMemberId,
42444
+ value: value.value,
42445
+ classId: stringOrNull(value.classId),
42446
+ ...typeof value.containerId === "string" ? { containerId: value.containerId } : {},
42447
+ ...isObjectRecord2(value.genericBindings) ? {
42448
+ genericBindings: Object.fromEntries(
42449
+ Object.entries(value.genericBindings).filter(
42450
+ (entry) => typeof entry[1] === "string"
42451
+ )
42452
+ )
42453
+ } : {}
42454
+ };
42455
+ }
42390
42456
  function preserveReboundValue(context, currentValueId, nextValueId, binding) {
42391
42457
  if (currentValueId === null || currentValueId === nextValueId) return;
42392
42458
  const base = valueBase(context, currentValueId);
@@ -42598,6 +42664,11 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
42598
42664
  valueId,
42599
42665
  value: expression.value
42600
42666
  });
42667
+ context.pendingLocalizedTexts.set(textId, {
42668
+ id: textId,
42669
+ valueId,
42670
+ value: expression.value
42671
+ });
42601
42672
  value = textId;
42602
42673
  } else {
42603
42674
  const lowered = lowerValueBody(
@@ -42645,6 +42716,7 @@ function lowerSeedChild(context, member, expression, source, path, rows, localiz
42645
42716
  return valueId;
42646
42717
  }
42647
42718
  function lowerValueRow(context, member, sourceExpression, expectedValueId, source, environment) {
42719
+ context.loweredMemberIdByValueId.set(expectedValueId, member.id);
42648
42720
  const { expression, id: id2 } = annotatedValue(sourceExpression);
42649
42721
  if (id2 !== null && id2 !== expectedValueId) {
42650
42722
  throw new Error(
@@ -43135,7 +43207,7 @@ function lowerListValue(context, member, expression, base, source, inheritedEnvi
43135
43207
  const environment = valueGenericEnvironment(base, inheritedEnvironment);
43136
43208
  const existingIds = existingListItemIds(context, member, base);
43137
43209
  const ids = [];
43138
- for (const element of expression.elements) {
43210
+ for (const [index, element] of expression.elements.entries()) {
43139
43211
  const symbolId = sourceValueSymbol(context, element);
43140
43212
  if (symbolId !== null) {
43141
43213
  if (!existingIds.has(symbolId)) {
@@ -43146,12 +43218,27 @@ function lowerListValue(context, member, expression, base, source, inheritedEnvi
43146
43218
  ids.push(symbolId);
43147
43219
  continue;
43148
43220
  }
43149
- const itemId = annotatedValue(element).id;
43150
- if (itemId === null) {
43151
- throw new Error(
43152
- `List ${member.name} contains an idless item. New list item creation is not implemented by this slice.`
43221
+ const annotatedItemId = annotatedValue(element).id;
43222
+ if (annotatedItemId === null) {
43223
+ if (source.purpose === "memberDefault") {
43224
+ throw new Error(
43225
+ `List ${member.name} contains an idless default item. New default list item creation is not implemented by this slice.`
43226
+ );
43227
+ }
43228
+ ids.push(
43229
+ lowerPendingListItem(
43230
+ context,
43231
+ entryMember,
43232
+ element,
43233
+ source,
43234
+ `${String(base.id)}[${index}]`,
43235
+ member.listKind === "unordered" ? stringOrNull(base.id) : void 0,
43236
+ environment
43237
+ )
43153
43238
  );
43239
+ continue;
43154
43240
  }
43241
+ const itemId = annotatedItemId;
43155
43242
  const child = valueBase(context, itemId);
43156
43243
  if (member.listKind === "unordered" && child.containerId !== base.id) {
43157
43244
  throw new Error(
@@ -43167,6 +43254,25 @@ function lowerListValue(context, member, expression, base, source, inheritedEnvi
43167
43254
  value: member.listKind === "unordered" ? [] : ids
43168
43255
  };
43169
43256
  }
43257
+ function lowerPendingListItem(context, member, expression, source, path, containerId, environment) {
43258
+ const rows = /* @__PURE__ */ new Map();
43259
+ const localizedTexts = /* @__PURE__ */ new Map();
43260
+ const valueId = lowerSeedChild(
43261
+ context,
43262
+ member,
43263
+ expression,
43264
+ source,
43265
+ path,
43266
+ rows,
43267
+ localizedTexts,
43268
+ containerId ?? void 0,
43269
+ environment
43270
+ );
43271
+ for (const text of localizedTexts.values()) {
43272
+ context.pendingLocalizedTexts.set(text.id, text);
43273
+ }
43274
+ return valueId;
43275
+ }
43170
43276
  function existingListItemIds(context, member, base) {
43171
43277
  if (member.listKind === "unordered") {
43172
43278
  const containerId = stringOrNull(base.id);
@@ -43700,6 +43806,7 @@ function indexSourceStaticTargets(targets, state, analysis, manifest, parsedInit
43700
43806
  annotatedValue(expression).id ?? current ?? pendingValueId(
43701
43807
  {
43702
43808
  memberId,
43809
+ purpose: "stored",
43703
43810
  initializer: declaration.initializer,
43704
43811
  source: declaration.source,
43705
43812
  label: symbol
@@ -43902,7 +44009,7 @@ function staticValueIdsBySymbol(state, manifest) {
43902
44009
  }
43903
44010
  return result;
43904
44011
  }
43905
- function projectFileIdsBySymbol(state) {
44012
+ function projectFileIdsBySymbol(state, analysis) {
43906
44013
  const files = Object.values(state).flatMap((record3) => {
43907
44014
  if (record3.recordKind !== "project-file" || !isObjectRecord2(record3.data))
43908
44015
  return [];
@@ -43911,12 +44018,21 @@ function projectFileIdsBySymbol(state) {
43911
44018
  return kind === "image" || kind === "audio" ? [{ stableId: record3.recordId, path: name, kind }] : [];
43912
44019
  });
43913
44020
  const symbols = assignDeterministicFileSymbols(files);
43914
- return new Map(
44021
+ const result = new Map(
43915
44022
  files.map((file) => [
43916
44023
  `${file.kind === "image" ? "Images" : "AudioClips"}.${symbols.get(file.stableId)}`,
43917
44024
  file.stableId
43918
44025
  ])
43919
44026
  );
44027
+ if (analysis !== void 0) {
44028
+ for (const declaration of projectFileDeclarationsV4(analysis)) {
44029
+ result.set(
44030
+ `${declaration.kind === "image" ? "Images" : "AudioClips"}.${declaration.symbol}`,
44031
+ declaration.recordId
44032
+ );
44033
+ }
44034
+ }
44035
+ return result;
43920
44036
  }
43921
44037
  function projectMainLocaleFromState(state) {
43922
44038
  const config = Object.values(state).find(
@@ -44663,17 +44779,18 @@ ${declarations.join("\n\n")}
44663
44779
  }
44664
44780
  function lowerProjectRootSourceV4(state, analysis, manifest) {
44665
44781
  const validated = validateProjectRootEnvelopeV4(state, analysis);
44666
- if (validated === null) return [];
44782
+ if (validated === null) {
44783
+ return { records: [], memberValueIds: /* @__PURE__ */ new Map(), seeds: /* @__PURE__ */ new Map() };
44784
+ }
44667
44785
  const { expectedIds, global, slots } = validated;
44668
44786
  const bindings = PROJECT_ROOT_SOURCE_SLOTS.map((expected, index) => ({
44669
44787
  memberId: expectedIds[index],
44788
+ purpose: "stored",
44670
44789
  initializer: slots[index].initializer,
44671
44790
  source: global.source,
44672
44791
  label: `root.${expected.name}`
44673
44792
  }));
44674
- return [
44675
- ...lowerStoredValueBindingsV4(state, manifest, bindings, { analysis }).records
44676
- ];
44793
+ return lowerStoredValueBindingsV4(state, manifest, bindings, { analysis });
44677
44794
  }
44678
44795
  function validateProjectRootEnvelopeV4(state, analysis) {
44679
44796
  const project = Object.values(state).find(
@@ -48185,7 +48302,10 @@ function computeWorkspaceStatus(workspace, options = {}) {
48185
48302
  }
48186
48303
  manifest = lowerProjectSchemaV4(baseManifest, analysis, {
48187
48304
  staticValueIdsBySymbol: staticValueIdsBySymbol2(workspace.state.records),
48188
- projectFileIdsBySymbol: projectFileIdsBySymbol(workspace.state.records),
48305
+ projectFileIdsBySymbol: projectFileIdsBySymbol(
48306
+ workspace.state.records,
48307
+ analysis
48308
+ ),
48189
48309
  rowBackedDefaultMemberIds: rowBackedDefaultMemberIdsV4(
48190
48310
  workspace.state.records
48191
48311
  )
@@ -48271,11 +48391,13 @@ function computeWorkspaceStatus(workspace, options = {}) {
48271
48391
  );
48272
48392
  staticValueSeeds = new Map([...staticValues.seeds, ...memberDefaults.seeds]);
48273
48393
  staticMemberValueIds = staticValues.memberValueIds;
48274
- const rootRecords = lowerProjectRootSourceV4(
48394
+ const rootValues = lowerProjectRootSourceV4(
48275
48395
  workspace.state.records,
48276
48396
  projectAnalysisV4,
48277
48397
  manifest
48278
48398
  );
48399
+ staticValueSeeds = new Map([...staticValueSeeds, ...rootValues.seeds]);
48400
+ const rootRecords = rootValues.records;
48279
48401
  const supplementalRecords = lowerSupplementalProjectSourcesV4(
48280
48402
  workspace.root,
48281
48403
  workspace.state.records,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neocompose/cli",
3
- "version": "0.9.1",
3
+ "version": "0.9.2",
4
4
  "description": "Neo Compose native project-source CLI with bidirectional sync.",
5
5
  "license": "MIT",
6
6
  "type": "module",