@neocompose/cli 0.31.14 → 0.31.15

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,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.31.15] - 2026-08-18
4
+
5
+ ### Fixed
6
+
7
+ - Accept authored internal record relation creates without server-owned project
8
+ and timestamp metadata, including durable pushes, and mirror the server's
9
+ metadata stamping during dry-run validation.
10
+
3
11
  ## [0.31.14] - 2026-08-18
4
12
 
5
13
  ### Fixed
package/dist/neo.mjs CHANGED
@@ -49214,9 +49214,16 @@ function isProjectRecordKind(value) {
49214
49214
  return false;
49215
49215
  }
49216
49216
  function isInternalRecordRelation(value) {
49217
- if (!isWithId(value)) return false;
49217
+ if (!isAuthoredInternalRecordRelation(value)) return false;
49218
49218
  const relation = value;
49219
49219
  if (!isString(relation.projectId)) return false;
49220
+ if (!isNumber(relation.createdAt)) return false;
49221
+ return isNumber(relation.updatedAt);
49222
+ }
49223
+ function isAuthoredInternalRecordRelation(value) {
49224
+ if (!isWithId(value)) return false;
49225
+ if (value.id.length === 0) return false;
49226
+ const relation = value;
49220
49227
  if (!isString(relation.relationKind)) return false;
49221
49228
  if (relation.relationKind.length === 0) return false;
49222
49229
  if (!isProjectRecordKind(relation.sourceRecordKind)) return false;
@@ -49228,8 +49235,7 @@ function isInternalRecordRelation(value) {
49228
49235
  if (relation.orderKey !== void 0 && (!isString(relation.orderKey) || relation.orderKey.length === 0)) {
49229
49236
  return false;
49230
49237
  }
49231
- if (!isNumber(relation.createdAt)) return false;
49232
- return isNumber(relation.updatedAt);
49238
+ return true;
49233
49239
  }
49234
49240
  function isProjectVersionSemver(value) {
49235
49241
  if (!isObject(value)) return false;
@@ -81254,23 +81260,6 @@ function isPushIntentInternalRecordRelation(value, operation) {
81254
81260
  }
81255
81261
  return isInternalRecordRelation(value);
81256
81262
  }
81257
- function isAuthoredInternalRecordRelation(value) {
81258
- if (!isObjectRecord5(value)) return false;
81259
- if (!isNonEmptyString3(value.id)) return false;
81260
- if (!isNonEmptyString3(value.relationKind)) return false;
81261
- if (!isProjectRecordKind(value.sourceRecordKind)) return false;
81262
- if (!isNonEmptyString3(value.sourceRecordId)) return false;
81263
- if (!isProjectRecordKind(value.targetRecordKind)) return false;
81264
- if (!isNonEmptyString3(value.targetRecordId)) return false;
81265
- if (value.orderKey === void 0) return true;
81266
- return isNonEmptyString3(value.orderKey);
81267
- }
81268
- function isObjectRecord5(value) {
81269
- return typeof value === "object" && value !== null && !Array.isArray(value);
81270
- }
81271
- function isNonEmptyString3(value) {
81272
- return typeof value === "string" && value.length > 0;
81273
- }
81274
81263
  var init_push_change_intent = __esm({
81275
81264
  "src/commands/push-change-intent.ts"() {
81276
81265
  "use strict";
@@ -94520,13 +94509,24 @@ function sortSeedRows(values) {
94520
94509
  return 0;
94521
94510
  });
94522
94511
  }
94523
- function stampServerOwnedSourceCommitTimestamps(args) {
94512
+ function stampServerOwnedSourceCommitMetadata(args) {
94524
94513
  if (!isObjectRecord2(args.rawDocument)) {
94525
94514
  throw new ProjectSourceCommitVerificationError(
94526
94515
  "Authoritative project document must be an object."
94527
94516
  );
94528
94517
  }
94529
94518
  const raw = args.rawDocument;
94519
+ const project = raw.project;
94520
+ if (!isObjectRecord2(project) || typeof project.id !== "string") {
94521
+ throw new ProjectSourceCommitVerificationError(
94522
+ "Authoritative project document must contain a project id."
94523
+ );
94524
+ }
94525
+ if (project.id.length === 0) {
94526
+ throw new ProjectSourceCommitVerificationError(
94527
+ "Authoritative project document project id must not be empty."
94528
+ );
94529
+ }
94530
94530
  const now = args.timestamp ?? Date.now();
94531
94531
  if (!Number.isSafeInteger(now)) {
94532
94532
  throw new ProjectSourceCommitVerificationError(
@@ -94542,6 +94542,11 @@ function stampServerOwnedSourceCommitTimestamps(args) {
94542
94542
  if (change.operation === "delete") return change;
94543
94543
  if (!isObjectRecord2(change.nextData)) return change;
94544
94544
  const stamped = { ...change.nextData };
94545
+ if (change.recordKind === "project") {
94546
+ delete stamped.projectId;
94547
+ } else {
94548
+ stamped.projectId = project.id;
94549
+ }
94545
94550
  if (change.operation === "create") {
94546
94551
  stamped.createdAt = now;
94547
94552
  stamped.updatedAt = now;
@@ -94698,7 +94703,7 @@ function prepareServerPreparationChanges(args) {
94698
94703
  `${change.recordKind}:${change.recordId}`
94699
94704
  )
94700
94705
  }));
94701
- const trustedChanges = stampServerOwnedSourceCommitTimestamps({
94706
+ const trustedChanges = stampServerOwnedSourceCommitMetadata({
94702
94707
  rawDocument,
94703
94708
  changes
94704
94709
  });
@@ -108671,11 +108676,11 @@ function assertProjectFileAuthoringRecordIdentifiers(recordKind, data) {
108671
108676
  if (recordKind !== "unity-texture-template" && recordKind !== "unity-audio-clip-template") {
108672
108677
  return;
108673
108678
  }
108674
- if (!isObjectRecord6(data) || typeof data.name !== "string") return;
108679
+ if (!isObjectRecord5(data) || typeof data.name !== "string") return;
108675
108680
  const label = recordKind === "unity-texture-template" ? "Unity texture template name" : "Unity audio clip template name";
108676
108681
  assertProjectFileAuthoringIdentifier(data.name, label);
108677
108682
  }
108678
- function isObjectRecord6(value) {
108683
+ function isObjectRecord5(value) {
108679
108684
  return typeof value === "object" && value !== null && !Array.isArray(value);
108680
108685
  }
108681
108686
  var init_project_file_authoring_identifiers = __esm({
@@ -108686,12 +108691,13 @@ var init_project_file_authoring_identifiers = __esm({
108686
108691
  });
108687
108692
 
108688
108693
  // ../src/database/project-version-validation.ts
108689
- function validateProjectRecordByKind(recordKind, data) {
108694
+ function validateProjectRecordByKind(recordKind, data, options = {}) {
108690
108695
  if (recordKind === ProjectRecordKind.Project) {
108691
108696
  if (isProject(data)) return;
108692
108697
  }
108693
108698
  if (recordKind === ProjectRecordKind.Member) {
108694
- if (isAnyMember(data)) return;
108699
+ const memberGuard = options.members === "authored-or-compiled" ? isAnyMemberAuthoredOrCompiled : isAnyMember;
108700
+ if (memberGuard(data)) return;
108695
108701
  }
108696
108702
  if (recordKind === ProjectRecordKind.Value) {
108697
108703
  if (isMemberValue(data)) return;
@@ -111624,7 +111630,7 @@ var init_registry2 = __esm({
111624
111630
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
111625
111631
  formatVersion: 3,
111626
111632
  contractVersion: "3.13",
111627
- cliVersion: "0.31.14",
111633
+ cliVersion: "0.31.15",
111628
111634
  projectFileUploadBatchSize: 32,
111629
111635
  documentRecords: {
111630
111636
  member: {
@@ -118219,7 +118225,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
118219
118225
  async function main() {
118220
118226
  const args = parseArgs(process.argv.slice(2));
118221
118227
  if (args.command === "--version") {
118222
- console.log("0.31.14");
118228
+ console.log("0.31.15");
118223
118229
  return;
118224
118230
  }
118225
118231
  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.31.14",
3
+ "version": "0.31.15",
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.31.14 -->
12
+ <!-- reviewed-through-cli: 0.31.15 -->
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.31.14 -->
86
+ <!-- reviewed-through-cli: 0.31.15 -->
87
87
  ```
88
88
 
89
89
  The quoted version above is checked too, so this instruction cannot go stale