@neocompose/cli 0.59.2 → 0.59.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.59.3] - 2026-09-26
4
+
5
+ - `neo doctor` keeps lookup references separate from owned values when auditing storage partitions. A world object referencing an entry in the main partition no longer reports that entry as malformed. Nested lookup entries in lists and dictionaries follow the same rule.
6
+
3
7
  ## [0.59.2] - 2026-09-25
4
8
 
5
9
  - Push is faster. A one-line change to the HelloWorld sample pushes in 3.0 s instead of 6.9 s.
package/dist/neo.mjs CHANGED
@@ -97793,12 +97793,12 @@ var init_project_version_transaction_planning = __esm({
97793
97793
  };
97794
97794
  CHUNK_FIXED_COST = addProjectVersionTransactionBudgets(CHUNK_GRAPH_VALIDATION_RESERVE, {
97795
97795
  argumentBytes: 256,
97796
- bytesRead: 32 * KIB,
97797
- bytesWritten: 48 * KIB,
97798
- documentsRead: 4,
97799
- documentsWritten: 5,
97800
- databaseQueries: 97,
97801
- indexRanges: 105,
97796
+ bytesRead: 266 * KIB,
97797
+ bytesWritten: 195 * KIB,
97798
+ documentsRead: 81,
97799
+ documentsWritten: 59,
97800
+ databaseQueries: 83,
97801
+ indexRanges: 83,
97802
97802
  functionsScheduled: 2,
97803
97803
  scheduledFunctionArgsBytes: 2 * KIB,
97804
97804
  returnBytes: 2 * KIB
@@ -97822,7 +97822,7 @@ var init_project_version_transaction_planning = __esm({
97822
97822
  databaseQueries: 410,
97823
97823
  indexRanges: 410
97824
97824
  };
97825
- CHANGE_BYTES_READ_OVERHEAD = 4 * KIB;
97825
+ CHANGE_BYTES_READ_OVERHEAD = 7 * KIB;
97826
97826
  CHANGE_BYTES_WRITTEN_OVERHEAD = 4 * KIB;
97827
97827
  }
97828
97828
  });
@@ -138486,7 +138486,16 @@ function auditProjectIntegrity(workspace) {
138486
138486
  const storedPlacements = buildStoredValuePlacementIndexV4(
138487
138487
  Object.values(records2)
138488
138488
  );
138489
- const placements = collectPlacements(values, storedPlacements);
138489
+ const lookupValueIds = collectLookupValueIds(
138490
+ records2,
138491
+ values,
138492
+ storedPlacements
138493
+ );
138494
+ const placements = collectPlacements(
138495
+ values,
138496
+ storedPlacements,
138497
+ lookupValueIds
138498
+ );
138490
138499
  const memberIdBySchemaKey = collectClassSchemas(records2);
138491
138500
  const storageKeyByMemberId = collectMemberStorageKeys(records2);
138492
138501
  const findings = [];
@@ -138703,7 +138712,7 @@ function collectValueRows(records2) {
138703
138712
  }
138704
138713
  return values;
138705
138714
  }
138706
- function collectPlacements(values, storedPlacements) {
138715
+ function collectPlacements(values, storedPlacements, lookupValueIds) {
138707
138716
  const placements = /* @__PURE__ */ new Map();
138708
138717
  const claim = (childId, placement) => {
138709
138718
  if (values.has(childId) && !placements.has(childId)) {
@@ -138719,6 +138728,7 @@ function collectPlacements(values, storedPlacements) {
138719
138728
  continue;
138720
138729
  }
138721
138730
  if (!Array.isArray(body)) continue;
138731
+ if (lookupValueIds.has(parent.id)) continue;
138722
138732
  for (const childId of body) {
138723
138733
  if (typeof childId === "string") {
138724
138734
  claim(childId, { parent, schemaKey: UNORDERED_MEMBERSHIP_KEY });
@@ -138739,6 +138749,57 @@ function collectPlacements(values, storedPlacements) {
138739
138749
  }
138740
138750
  return placements;
138741
138751
  }
138752
+ function collectLookupValueIds(records2, values, storedPlacements) {
138753
+ const members = /* @__PURE__ */ new Map();
138754
+ const pending = [];
138755
+ for (const record6 of Object.values(records2)) {
138756
+ if (record6.recordKind !== "member" || !isObjectRecord2(record6.data))
138757
+ continue;
138758
+ members.set(record6.recordId, record6.data);
138759
+ if (typeof record6.data.valueId === "string") {
138760
+ pending.push({ valueId: record6.data.valueId, memberId: record6.recordId });
138761
+ }
138762
+ }
138763
+ for (const edge of storedPlacements.placementByChildValueId.values()) {
138764
+ if (edge.memberId !== null) {
138765
+ pending.push({ valueId: edge.childValueId, memberId: edge.memberId });
138766
+ }
138767
+ }
138768
+ const contained = /* @__PURE__ */ new Map();
138769
+ for (const value of values.values()) {
138770
+ if (value.containerId === null) continue;
138771
+ const siblings = contained.get(value.containerId);
138772
+ if (siblings === void 0) contained.set(value.containerId, [value.id]);
138773
+ else siblings.push(value.id);
138774
+ }
138775
+ const lookups = /* @__PURE__ */ new Set();
138776
+ const visited = /* @__PURE__ */ new Set();
138777
+ for (let next = pending.pop(); next !== void 0; next = pending.pop()) {
138778
+ if (visited.has(next.valueId)) continue;
138779
+ visited.add(next.valueId);
138780
+ const member = members.get(next.memberId);
138781
+ if (member === void 0) continue;
138782
+ if (member.kind === 9 /* Lookup */ || member.kind === 18 /* DialogueLookup */) {
138783
+ lookups.add(next.valueId);
138784
+ continue;
138785
+ }
138786
+ if (member.kind !== 6 /* List */ && member.kind !== 5 /* Dictionary */)
138787
+ continue;
138788
+ const memberId = member.entryMemberId;
138789
+ if (typeof memberId !== "string") continue;
138790
+ const body = values.get(next.valueId)?.value;
138791
+ const children = isObjectRecord2(body) ? Object.values(body) : body;
138792
+ if (Array.isArray(children)) {
138793
+ for (const valueId of children) {
138794
+ if (typeof valueId === "string") pending.push({ valueId, memberId });
138795
+ }
138796
+ }
138797
+ for (const valueId of contained.get(next.valueId) ?? []) {
138798
+ pending.push({ valueId, memberId });
138799
+ }
138800
+ }
138801
+ return lookups;
138802
+ }
138742
138803
  function collectClassSchemas(records2) {
138743
138804
  const schemas = /* @__PURE__ */ new Map();
138744
138805
  for (const record6 of Object.values(records2)) {
@@ -138808,6 +138869,7 @@ var init_project_integrity = __esm({
138808
138869
  "use strict";
138809
138870
  init_member_storage_key();
138810
138871
  init_system_record_id();
138872
+ init_member_kind_enum();
138811
138873
  init_projection();
138812
138874
  init_stored_value_placements();
138813
138875
  UNORDERED_MEMBERSHIP_KEY = "(container)";
@@ -140881,7 +140943,7 @@ var init_registry2 = __esm({
140881
140943
  "schema-contract/registry.mjs"() {
140882
140944
  "use strict";
140883
140945
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
140884
- cliVersion: "0.59.2",
140946
+ cliVersion: "0.59.3",
140885
140947
  projectFileUploadBatchSize: 32,
140886
140948
  documentRecords: {
140887
140949
  member: {
@@ -148702,7 +148764,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
148702
148764
  async function main() {
148703
148765
  const args = parseArgs(process.argv.slice(2));
148704
148766
  if (args.command === "--version") {
148705
- console.log("0.59.2");
148767
+ console.log("0.59.3");
148706
148768
  return;
148707
148769
  }
148708
148770
  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.59.2",
3
+ "version": "0.59.3",
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.59.2 -->
12
+ <!-- reviewed-through-cli: 0.59.3 -->
13
13
 
14
14
  # Neo Compose CLI
15
15
 
@@ -101,7 +101,7 @@ wrappers.
101
101
  The marker near the top of `SKILL.md` must exactly match the package version:
102
102
 
103
103
  ```html
104
- <!-- reviewed-through-cli: 0.59.2 -->
104
+ <!-- reviewed-through-cli: 0.59.3 -->
105
105
  ```
106
106
 
107
107
  The quoted version above is checked too, so this instruction cannot go stale
@@ -239,13 +239,12 @@ run beneath a `neo.json`. An explicit `--api` takes priority. Outside a
239
239
  workspace, they use the CLI build's default API origin. Login prints the
240
240
  selected origin before it requests or stores a credential.
241
241
 
242
- `neo doctor` reports two different things. The authoring contracts (format,
243
- compiler, extension cache, source, files) decide its exit code; the document
244
- audit below them reports the last pull's malformed records, plus base rows no
245
- emitted file projects and no record names, and deliberately does not, so a
246
- project with records still to repair does not fail the command. An unprojected
247
- row is invisible to `neo status` by construction, which is why `neo doctor` is
248
- the only place it surfaces.
242
+ `neo doctor` checks authoring contracts (format, compiler, extension cache, source,
243
+ files) and the last pull's document integrity. Malformed records fail the command.
244
+ The partition audit follows ownership: a lookup can reference a value stored in a
245
+ different partition without moving it into the lookup's partition. The document
246
+ audit also reports base rows no emitted file projects and no record names; these
247
+ rows are invisible to `neo status`.
249
248
  `neo doctor --json` carries a `repair` entry per finding, which is what a
250
249
  targeted repair is handed instead of scanning a project to rediscover them.
251
250
  `neo doctor --fix` consumes those entries for the `unprojected-value-row`