@neocompose/cli 0.9.1 → 0.9.3

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/neo.mjs +150 -14
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,20 @@
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.3] - 2026-07-25
11
+
12
+ ### Fixed
13
+
14
+ - Re-lower provisional list rows as new value seeds during trusted source
15
+ verification instead of requiring them to exist in pulled state.
16
+
17
+ ## [0.9.2] - 2026-07-24
18
+
19
+ ### Fixed
20
+
21
+ - Create idless list entries inside existing stored value graphs, including
22
+ nested class subtrees and references to files created by the same push.
23
+
10
24
  ## [0.9.1] - 2026-07-24
11
25
 
12
26
  ### 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,11 +43218,40 @@ 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;
43240
+ }
43241
+ const itemId = annotatedItemId;
43242
+ if (isPendingId(itemId) && context.state[`value:${itemId}`] === void 0) {
43243
+ ids.push(
43244
+ lowerPendingListItem(
43245
+ context,
43246
+ entryMember,
43247
+ element,
43248
+ source,
43249
+ `${String(base.id)}[${index}]`,
43250
+ member.listKind === "unordered" ? stringOrNull(base.id) : void 0,
43251
+ environment
43252
+ )
43253
+ );
43254
+ continue;
43154
43255
  }
43155
43256
  const child = valueBase(context, itemId);
43156
43257
  if (member.listKind === "unordered" && child.containerId !== base.id) {
@@ -43167,6 +43268,25 @@ function lowerListValue(context, member, expression, base, source, inheritedEnvi
43167
43268
  value: member.listKind === "unordered" ? [] : ids
43168
43269
  };
43169
43270
  }
43271
+ function lowerPendingListItem(context, member, expression, source, path, containerId, environment) {
43272
+ const rows = /* @__PURE__ */ new Map();
43273
+ const localizedTexts = /* @__PURE__ */ new Map();
43274
+ const valueId = lowerSeedChild(
43275
+ context,
43276
+ member,
43277
+ expression,
43278
+ source,
43279
+ path,
43280
+ rows,
43281
+ localizedTexts,
43282
+ containerId ?? void 0,
43283
+ environment
43284
+ );
43285
+ for (const text of localizedTexts.values()) {
43286
+ context.pendingLocalizedTexts.set(text.id, text);
43287
+ }
43288
+ return valueId;
43289
+ }
43170
43290
  function existingListItemIds(context, member, base) {
43171
43291
  if (member.listKind === "unordered") {
43172
43292
  const containerId = stringOrNull(base.id);
@@ -43700,6 +43820,7 @@ function indexSourceStaticTargets(targets, state, analysis, manifest, parsedInit
43700
43820
  annotatedValue(expression).id ?? current ?? pendingValueId(
43701
43821
  {
43702
43822
  memberId,
43823
+ purpose: "stored",
43703
43824
  initializer: declaration.initializer,
43704
43825
  source: declaration.source,
43705
43826
  label: symbol
@@ -43902,7 +44023,7 @@ function staticValueIdsBySymbol(state, manifest) {
43902
44023
  }
43903
44024
  return result;
43904
44025
  }
43905
- function projectFileIdsBySymbol(state) {
44026
+ function projectFileIdsBySymbol(state, analysis) {
43906
44027
  const files = Object.values(state).flatMap((record3) => {
43907
44028
  if (record3.recordKind !== "project-file" || !isObjectRecord2(record3.data))
43908
44029
  return [];
@@ -43911,12 +44032,21 @@ function projectFileIdsBySymbol(state) {
43911
44032
  return kind === "image" || kind === "audio" ? [{ stableId: record3.recordId, path: name, kind }] : [];
43912
44033
  });
43913
44034
  const symbols = assignDeterministicFileSymbols(files);
43914
- return new Map(
44035
+ const result = new Map(
43915
44036
  files.map((file) => [
43916
44037
  `${file.kind === "image" ? "Images" : "AudioClips"}.${symbols.get(file.stableId)}`,
43917
44038
  file.stableId
43918
44039
  ])
43919
44040
  );
44041
+ if (analysis !== void 0) {
44042
+ for (const declaration of projectFileDeclarationsV4(analysis)) {
44043
+ result.set(
44044
+ `${declaration.kind === "image" ? "Images" : "AudioClips"}.${declaration.symbol}`,
44045
+ declaration.recordId
44046
+ );
44047
+ }
44048
+ }
44049
+ return result;
43920
44050
  }
43921
44051
  function projectMainLocaleFromState(state) {
43922
44052
  const config = Object.values(state).find(
@@ -44663,17 +44793,18 @@ ${declarations.join("\n\n")}
44663
44793
  }
44664
44794
  function lowerProjectRootSourceV4(state, analysis, manifest) {
44665
44795
  const validated = validateProjectRootEnvelopeV4(state, analysis);
44666
- if (validated === null) return [];
44796
+ if (validated === null) {
44797
+ return { records: [], memberValueIds: /* @__PURE__ */ new Map(), seeds: /* @__PURE__ */ new Map() };
44798
+ }
44667
44799
  const { expectedIds, global, slots } = validated;
44668
44800
  const bindings = PROJECT_ROOT_SOURCE_SLOTS.map((expected, index) => ({
44669
44801
  memberId: expectedIds[index],
44802
+ purpose: "stored",
44670
44803
  initializer: slots[index].initializer,
44671
44804
  source: global.source,
44672
44805
  label: `root.${expected.name}`
44673
44806
  }));
44674
- return [
44675
- ...lowerStoredValueBindingsV4(state, manifest, bindings, { analysis }).records
44676
- ];
44807
+ return lowerStoredValueBindingsV4(state, manifest, bindings, { analysis });
44677
44808
  }
44678
44809
  function validateProjectRootEnvelopeV4(state, analysis) {
44679
44810
  const project = Object.values(state).find(
@@ -48185,7 +48316,10 @@ function computeWorkspaceStatus(workspace, options = {}) {
48185
48316
  }
48186
48317
  manifest = lowerProjectSchemaV4(baseManifest, analysis, {
48187
48318
  staticValueIdsBySymbol: staticValueIdsBySymbol2(workspace.state.records),
48188
- projectFileIdsBySymbol: projectFileIdsBySymbol(workspace.state.records),
48319
+ projectFileIdsBySymbol: projectFileIdsBySymbol(
48320
+ workspace.state.records,
48321
+ analysis
48322
+ ),
48189
48323
  rowBackedDefaultMemberIds: rowBackedDefaultMemberIdsV4(
48190
48324
  workspace.state.records
48191
48325
  )
@@ -48271,11 +48405,13 @@ function computeWorkspaceStatus(workspace, options = {}) {
48271
48405
  );
48272
48406
  staticValueSeeds = new Map([...staticValues.seeds, ...memberDefaults.seeds]);
48273
48407
  staticMemberValueIds = staticValues.memberValueIds;
48274
- const rootRecords = lowerProjectRootSourceV4(
48408
+ const rootValues = lowerProjectRootSourceV4(
48275
48409
  workspace.state.records,
48276
48410
  projectAnalysisV4,
48277
48411
  manifest
48278
48412
  );
48413
+ staticValueSeeds = new Map([...staticValueSeeds, ...rootValues.seeds]);
48414
+ const rootRecords = rootValues.records;
48279
48415
  const supplementalRecords = lowerSupplementalProjectSourcesV4(
48280
48416
  workspace.root,
48281
48417
  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.3",
4
4
  "description": "Neo Compose native project-source CLI with bidirectional sync.",
5
5
  "license": "MIT",
6
6
  "type": "module",