@neocompose/cli 0.6.5 → 0.6.7
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 +25 -0
- package/dist/neo.mjs +269 -48
- package/package.json +1 -1
- package/skills/neocompose-cli/SKILL.md +8 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [Unreleased]
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Document the final relation-only world layer-link contract and keep the
|
|
8
|
+
format-4 Hello World corpus free of the retired value-side binding field.
|
|
9
|
+
|
|
10
|
+
## [0.6.7] - 2026-07-21
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Treat class-level layer-link relations, including inherited targets, as the
|
|
15
|
+
authoritative binding during pull, status, diff, and push.
|
|
16
|
+
- Reject concrete system layer-link bases, targetless concrete descendants,
|
|
17
|
+
ambiguous or invalid targets, abstract construction, and authored
|
|
18
|
+
`layerClassId` sidecars before a source transaction reaches the server.
|
|
19
|
+
|
|
20
|
+
## [0.6.6] - 2026-07-21
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Include relation-kind metadata when pushing internal record relations so
|
|
25
|
+
`@relations` changes pass server transaction admission.
|
|
26
|
+
- Report the actual HTTP response status when a push is rejected.
|
|
27
|
+
|
|
3
28
|
## [0.6.5] - 2026-07-21
|
|
4
29
|
|
|
5
30
|
### Fixed
|
package/dist/neo.mjs
CHANGED
|
@@ -13981,6 +13981,7 @@ function validateProjectSourceSemantics(documents) {
|
|
|
13981
13981
|
);
|
|
13982
13982
|
}
|
|
13983
13983
|
}
|
|
13984
|
+
validateWorldLayerLinkSourceContracts(documents, environment, diagnostics);
|
|
13984
13985
|
return diagnostics;
|
|
13985
13986
|
}
|
|
13986
13987
|
function contextualAnnotationFields(document, position) {
|
|
@@ -14500,6 +14501,188 @@ function relationFields(context, environment) {
|
|
|
14500
14501
|
}
|
|
14501
14502
|
return [];
|
|
14502
14503
|
}
|
|
14504
|
+
function validateWorldLayerLinkSourceContracts(documents, environment, diagnostics) {
|
|
14505
|
+
for (const [uri, document] of documents) {
|
|
14506
|
+
for (const declaration of document.declarations) {
|
|
14507
|
+
if (declaration.kind !== "class") continue;
|
|
14508
|
+
const descriptor = worldLayerLinkSourceDescriptor(
|
|
14509
|
+
declaration,
|
|
14510
|
+
environment
|
|
14511
|
+
);
|
|
14512
|
+
if (descriptor === null) continue;
|
|
14513
|
+
const directTargets = directLayerLinkTargets(declaration, uri);
|
|
14514
|
+
const systemWorldKind = contextualAnnotationEnum(
|
|
14515
|
+
declaration.annotations,
|
|
14516
|
+
"system",
|
|
14517
|
+
"worldKind"
|
|
14518
|
+
);
|
|
14519
|
+
const isSystemBase = systemWorldKind === descriptor.linkWorldKind;
|
|
14520
|
+
if (isSystemBase) {
|
|
14521
|
+
if (!declaration.modifiers.includes("abstract")) {
|
|
14522
|
+
pushDiagnostic(
|
|
14523
|
+
diagnostics,
|
|
14524
|
+
uri,
|
|
14525
|
+
declaration.nameRange,
|
|
14526
|
+
"concrete-system-layer-link-base",
|
|
14527
|
+
`System layer-link base '${declaration.name}' must be abstract.`
|
|
14528
|
+
);
|
|
14529
|
+
}
|
|
14530
|
+
if (directTargets.length > 0) {
|
|
14531
|
+
pushDiagnostic(
|
|
14532
|
+
diagnostics,
|
|
14533
|
+
uri,
|
|
14534
|
+
directTargets[0].range,
|
|
14535
|
+
"system-layer-link-target-relation",
|
|
14536
|
+
`System layer-link base '${declaration.name}' cannot declare targetLayer. Declare the relation on a project-authored descendant instead.`
|
|
14537
|
+
);
|
|
14538
|
+
}
|
|
14539
|
+
}
|
|
14540
|
+
for (const target of directTargets) {
|
|
14541
|
+
validateLayerLinkTargetSource(
|
|
14542
|
+
declaration,
|
|
14543
|
+
descriptor,
|
|
14544
|
+
target,
|
|
14545
|
+
environment,
|
|
14546
|
+
diagnostics
|
|
14547
|
+
);
|
|
14548
|
+
}
|
|
14549
|
+
if (isSystemBase || declaration.modifiers.includes("abstract")) continue;
|
|
14550
|
+
const effectiveTargets = effectiveLayerLinkTargets(
|
|
14551
|
+
declaration,
|
|
14552
|
+
uri,
|
|
14553
|
+
environment
|
|
14554
|
+
);
|
|
14555
|
+
if (effectiveTargets.length === 0) {
|
|
14556
|
+
pushDiagnostic(
|
|
14557
|
+
diagnostics,
|
|
14558
|
+
uri,
|
|
14559
|
+
declaration.nameRange,
|
|
14560
|
+
"concrete-layer-link-missing-target",
|
|
14561
|
+
`Concrete layer-link class '${declaration.name}' must resolve exactly one inherited or directly declared targetLayer relation.`
|
|
14562
|
+
);
|
|
14563
|
+
} else if (effectiveTargets.length > 1) {
|
|
14564
|
+
pushDiagnostic(
|
|
14565
|
+
diagnostics,
|
|
14566
|
+
uri,
|
|
14567
|
+
declaration.nameRange,
|
|
14568
|
+
"concrete-layer-link-multiple-targets",
|
|
14569
|
+
`Concrete layer-link class '${declaration.name}' resolves ${effectiveTargets.length} targetLayer relations at the nearest declaration depth; exactly one is required.`
|
|
14570
|
+
);
|
|
14571
|
+
}
|
|
14572
|
+
}
|
|
14573
|
+
}
|
|
14574
|
+
}
|
|
14575
|
+
function worldLayerLinkSourceDescriptor(declaration, environment) {
|
|
14576
|
+
const worldKind = effectiveWorldKind(declaration, environment);
|
|
14577
|
+
if (worldKind === "TileLayerLink") {
|
|
14578
|
+
return {
|
|
14579
|
+
linkWorldKind: "TileLayerLink",
|
|
14580
|
+
targetWorldKind: "TileLayer"
|
|
14581
|
+
};
|
|
14582
|
+
}
|
|
14583
|
+
if (worldKind === "ObjectLayerLink") {
|
|
14584
|
+
return {
|
|
14585
|
+
linkWorldKind: "ObjectLayerLink",
|
|
14586
|
+
targetWorldKind: "ObjectLayer"
|
|
14587
|
+
};
|
|
14588
|
+
}
|
|
14589
|
+
return null;
|
|
14590
|
+
}
|
|
14591
|
+
function directLayerLinkTargets(declaration, uri) {
|
|
14592
|
+
const result = [];
|
|
14593
|
+
for (const annotation2 of declaration.annotations) {
|
|
14594
|
+
if (annotation2.name !== "relations") continue;
|
|
14595
|
+
for (const argument2 of annotation2.arguments) {
|
|
14596
|
+
if (argument2.name !== "targetLayer") continue;
|
|
14597
|
+
let expression;
|
|
14598
|
+
try {
|
|
14599
|
+
expression = parseExpression(argument2.text);
|
|
14600
|
+
} catch (error) {
|
|
14601
|
+
if (error instanceof CompileError) continue;
|
|
14602
|
+
throw error;
|
|
14603
|
+
}
|
|
14604
|
+
const entries = expression.kind === "litList" ? expression.elements : [expression];
|
|
14605
|
+
for (const entry of entries) {
|
|
14606
|
+
result.push({
|
|
14607
|
+
expression: unwrapAnnotatedExpression(entry),
|
|
14608
|
+
range: argument2.range,
|
|
14609
|
+
uri
|
|
14610
|
+
});
|
|
14611
|
+
}
|
|
14612
|
+
}
|
|
14613
|
+
}
|
|
14614
|
+
return result;
|
|
14615
|
+
}
|
|
14616
|
+
function effectiveLayerLinkTargets(declaration, uri, environment) {
|
|
14617
|
+
const visited = /* @__PURE__ */ new Set();
|
|
14618
|
+
let current = declaration;
|
|
14619
|
+
let currentUri = uri;
|
|
14620
|
+
while (current !== void 0 && !visited.has(current.name)) {
|
|
14621
|
+
visited.add(current.name);
|
|
14622
|
+
const systemWorldKind = contextualAnnotationEnum(
|
|
14623
|
+
current.annotations,
|
|
14624
|
+
"system",
|
|
14625
|
+
"worldKind"
|
|
14626
|
+
);
|
|
14627
|
+
if (systemWorldKind === "TileLayerLink" || systemWorldKind === "ObjectLayerLink") {
|
|
14628
|
+
return [];
|
|
14629
|
+
}
|
|
14630
|
+
const direct = directLayerLinkTargets(current, currentUri);
|
|
14631
|
+
if (direct.length > 0) return direct;
|
|
14632
|
+
const parent = current.baseTypes.map((base) => environment.types.get(base.name)).find((candidate) => candidate !== void 0);
|
|
14633
|
+
current = parent;
|
|
14634
|
+
currentUri = uri;
|
|
14635
|
+
}
|
|
14636
|
+
return [];
|
|
14637
|
+
}
|
|
14638
|
+
function validateLayerLinkTargetSource(declaration, descriptor, targetSource, environment, diagnostics) {
|
|
14639
|
+
const expression = targetSource.expression;
|
|
14640
|
+
if (isReferenceCall(expression)) return;
|
|
14641
|
+
if (expression.kind !== "ident") {
|
|
14642
|
+
pushDiagnostic(
|
|
14643
|
+
diagnostics,
|
|
14644
|
+
targetSource.uri,
|
|
14645
|
+
targetSource.range,
|
|
14646
|
+
"invalid-layer-link-target",
|
|
14647
|
+
`Layer-link class '${declaration.name}' targetLayer must be a layer class symbol or typed Reference.`
|
|
14648
|
+
);
|
|
14649
|
+
return;
|
|
14650
|
+
}
|
|
14651
|
+
const target = environment.types.get(expression.name);
|
|
14652
|
+
if (target === void 0) {
|
|
14653
|
+
pushDiagnostic(
|
|
14654
|
+
diagnostics,
|
|
14655
|
+
targetSource.uri,
|
|
14656
|
+
targetSource.range,
|
|
14657
|
+
"unknown-layer-link-target",
|
|
14658
|
+
`Layer-link class '${declaration.name}' targets unknown class '${expression.name}'.`
|
|
14659
|
+
);
|
|
14660
|
+
return;
|
|
14661
|
+
}
|
|
14662
|
+
const targetWorldKind = effectiveWorldKind(target, environment);
|
|
14663
|
+
if (targetWorldKind !== descriptor.targetWorldKind) {
|
|
14664
|
+
pushDiagnostic(
|
|
14665
|
+
diagnostics,
|
|
14666
|
+
targetSource.uri,
|
|
14667
|
+
targetSource.range,
|
|
14668
|
+
"wrong-layer-link-target-kind",
|
|
14669
|
+
`Layer-link class '${declaration.name}' targetLayer '${target.name}' must extend world class kind '${descriptor.targetWorldKind}'.`
|
|
14670
|
+
);
|
|
14671
|
+
return;
|
|
14672
|
+
}
|
|
14673
|
+
if (target.modifiers.includes("abstract")) {
|
|
14674
|
+
pushDiagnostic(
|
|
14675
|
+
diagnostics,
|
|
14676
|
+
targetSource.uri,
|
|
14677
|
+
targetSource.range,
|
|
14678
|
+
"abstract-layer-link-target",
|
|
14679
|
+
`Layer-link class '${declaration.name}' targetLayer '${target.name}' must be concrete.`
|
|
14680
|
+
);
|
|
14681
|
+
}
|
|
14682
|
+
}
|
|
14683
|
+
function unwrapAnnotatedExpression(expression) {
|
|
14684
|
+
return expression.kind === "annotated" ? unwrapAnnotatedExpression(expression.expression) : expression;
|
|
14685
|
+
}
|
|
14503
14686
|
function effectiveWorldKind(declaration, environment) {
|
|
14504
14687
|
const queue = [declaration];
|
|
14505
14688
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -14829,7 +15012,26 @@ function validateExpression(expression, expected, scope, environment, uri, range
|
|
|
14829
15012
|
if (expression.kind === "new") {
|
|
14830
15013
|
const typeName = expression.className ?? expected?.name;
|
|
14831
15014
|
const declaration = typeName ? environment.types.get(typeName) : void 0;
|
|
15015
|
+
for (const entry of expression.initializer ?? []) {
|
|
15016
|
+
if (entry.name !== "layerClassId") continue;
|
|
15017
|
+
pushDiagnostic(
|
|
15018
|
+
diagnostics,
|
|
15019
|
+
uri,
|
|
15020
|
+
range2,
|
|
15021
|
+
"reserved-layer-class-id-source",
|
|
15022
|
+
"layerClassId is an unsupported legacy field. Declare @relations(targetLayer: ...) on the concrete layer-link class instead."
|
|
15023
|
+
);
|
|
15024
|
+
}
|
|
14832
15025
|
if (!declaration) return;
|
|
15026
|
+
if (declaration.modifiers.includes("abstract")) {
|
|
15027
|
+
pushDiagnostic(
|
|
15028
|
+
diagnostics,
|
|
15029
|
+
uri,
|
|
15030
|
+
range2,
|
|
15031
|
+
"abstract-class-instantiation",
|
|
15032
|
+
`Cannot instantiate abstract class '${declaration.name}'. Use a concrete descendant instead.`
|
|
15033
|
+
);
|
|
15034
|
+
}
|
|
14833
15035
|
const fields = declaration?.members.filter(
|
|
14834
15036
|
(member) => member.kind === "field" && !member.modifiers.includes("static")
|
|
14835
15037
|
) ?? [];
|
|
@@ -14847,8 +15049,10 @@ function validateExpression(expression, expected, scope, environment, uri, range
|
|
|
14847
15049
|
);
|
|
14848
15050
|
});
|
|
14849
15051
|
for (const entry of expression.initializer ?? []) {
|
|
14850
|
-
const field =
|
|
14851
|
-
|
|
15052
|
+
const field = sourceClassFieldByName(
|
|
15053
|
+
declaration,
|
|
15054
|
+
entry.name,
|
|
15055
|
+
environment
|
|
14852
15056
|
);
|
|
14853
15057
|
validateExpression(
|
|
14854
15058
|
entry.value,
|
|
@@ -14950,6 +15154,19 @@ function validateExpression(expression, expected, scope, environment, uri, range
|
|
|
14950
15154
|
);
|
|
14951
15155
|
}
|
|
14952
15156
|
}
|
|
15157
|
+
function sourceClassFieldByName(declaration, name, environment) {
|
|
15158
|
+
const visited = /* @__PURE__ */ new Set();
|
|
15159
|
+
let current = declaration;
|
|
15160
|
+
while (current !== void 0 && !visited.has(current.name)) {
|
|
15161
|
+
visited.add(current.name);
|
|
15162
|
+
const member = current.members.find(
|
|
15163
|
+
(candidate) => candidate.kind === "field" && candidate.name === name
|
|
15164
|
+
);
|
|
15165
|
+
if (member !== void 0) return member;
|
|
15166
|
+
current = current.baseTypes.map((base) => environment.types.get(base.name)).find((candidate) => candidate !== void 0);
|
|
15167
|
+
}
|
|
15168
|
+
return void 0;
|
|
15169
|
+
}
|
|
14953
15170
|
function semanticTypesAssignable(actual, expected) {
|
|
14954
15171
|
if (actual.name === expected.name) return true;
|
|
14955
15172
|
if (actual.name === "int" && (expected.name === "float" || expected.name === "decimal")) {
|
|
@@ -40331,6 +40548,11 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
|
|
|
40331
40548
|
if (effectiveClass === void 0) {
|
|
40332
40549
|
throw new Error(`Unknown value class ${member.classId}.`);
|
|
40333
40550
|
}
|
|
40551
|
+
if (effectiveClass.declarationModifier === "abstract") {
|
|
40552
|
+
throw new Error(
|
|
40553
|
+
`Cannot instantiate abstract class ${effectiveClass.name} for ${path}. Use a concrete descendant instead.`
|
|
40554
|
+
);
|
|
40555
|
+
}
|
|
40334
40556
|
classId = effectiveClass.id;
|
|
40335
40557
|
const body = {};
|
|
40336
40558
|
for (const assignment of expression.initializer ?? []) {
|
|
@@ -40528,6 +40750,11 @@ function lowerClassValue(context, member, expression, base, source) {
|
|
|
40528
40750
|
const schemaClass2 = context.classes.get(classId);
|
|
40529
40751
|
if (schemaClass2 === void 0)
|
|
40530
40752
|
throw new Error(`Unknown value class ${classId}.`);
|
|
40753
|
+
if (schemaClass2.declarationModifier === "abstract") {
|
|
40754
|
+
throw new Error(
|
|
40755
|
+
`Cannot instantiate abstract class ${schemaClass2.name} for value ${String(base.id)}. Use a concrete descendant instead.`
|
|
40756
|
+
);
|
|
40757
|
+
}
|
|
40531
40758
|
const baseBody = isObjectRecord2(base.value) ? base.value : {};
|
|
40532
40759
|
const body = { ...baseBody };
|
|
40533
40760
|
for (const assignment of expression.initializer ?? []) {
|
|
@@ -41368,7 +41595,7 @@ function classValue(context, member, value, visited, targetTyped) {
|
|
|
41368
41595
|
return targetTyped ? "new()" : `new ${name}()`;
|
|
41369
41596
|
const schema = isObjectRecord2(schemaClass2.schema) ? schemaClass2.schema : {};
|
|
41370
41597
|
const order = Array.isArray(schemaClass2.schemaKeyOrder) ? schemaClass2.schemaKeyOrder.filter(
|
|
41371
|
-
(entry) => typeof entry === "string"
|
|
41598
|
+
(entry) => typeof entry === "string" && typeof schema[entry] === "string"
|
|
41372
41599
|
) : Object.keys(schema);
|
|
41373
41600
|
const fields = [];
|
|
41374
41601
|
for (const key of [
|
|
@@ -44914,7 +45141,7 @@ var init_project_migration_types = __esm({
|
|
|
44914
45141
|
});
|
|
44915
45142
|
|
|
44916
45143
|
// ../src/models/project/internal-record-relations.ts
|
|
44917
|
-
function worldClassContract(relationKind, sourceWorldKind, targetWorldKind, targetClassPolicy, merge, allowAbstractTarget) {
|
|
45144
|
+
function worldClassContract(relationKind, sourceWorldKind, targetWorldKind, targetClassPolicy, merge, allowAbstractTarget, allowDirectSystemSource = true) {
|
|
44918
45145
|
return {
|
|
44919
45146
|
relationKind,
|
|
44920
45147
|
endpointPairs: [{ sourceRecordKind: "class", targetRecordKind: "class" }],
|
|
@@ -44924,6 +45151,7 @@ function worldClassContract(relationKind, sourceWorldKind, targetWorldKind, targ
|
|
|
44924
45151
|
allowCycles: false,
|
|
44925
45152
|
sourceWorldKind,
|
|
44926
45153
|
targetWorldKind,
|
|
45154
|
+
allowDirectSystemSource,
|
|
44927
45155
|
allowAbstractTarget
|
|
44928
45156
|
};
|
|
44929
45157
|
}
|
|
@@ -45018,6 +45246,7 @@ var init_internal_record_relations = __esm({
|
|
|
45018
45246
|
NeoWorldSystemClassKind.TileLayer,
|
|
45019
45247
|
"exact",
|
|
45020
45248
|
"nearest-single",
|
|
45249
|
+
false,
|
|
45021
45250
|
false
|
|
45022
45251
|
),
|
|
45023
45252
|
worldClassContract(
|
|
@@ -45026,6 +45255,7 @@ var init_internal_record_relations = __esm({
|
|
|
45026
45255
|
NeoWorldSystemClassKind.ObjectLayer,
|
|
45027
45256
|
"exact",
|
|
45028
45257
|
"nearest-single",
|
|
45258
|
+
false,
|
|
45029
45259
|
false
|
|
45030
45260
|
),
|
|
45031
45261
|
{
|
|
@@ -49561,15 +49791,6 @@ var init_doctor = __esm({
|
|
|
49561
49791
|
});
|
|
49562
49792
|
|
|
49563
49793
|
// ../src/database/project-version-intents.ts
|
|
49564
|
-
var project_version_intents_exports = {};
|
|
49565
|
-
__export(project_version_intents_exports, {
|
|
49566
|
-
PROJECT_VERSION_INTENT_SCHEMA_VERSION: () => PROJECT_VERSION_INTENT_SCHEMA_VERSION,
|
|
49567
|
-
ProjectVersionIntentType: () => ProjectVersionIntentType,
|
|
49568
|
-
assertProjectVersionIntentIsKnown: () => assertProjectVersionIntentIsKnown,
|
|
49569
|
-
assertProjectVersionIntentMatchesDiff: () => assertProjectVersionIntentMatchesDiff,
|
|
49570
|
-
createProjectVersionIntent: () => createProjectVersionIntent,
|
|
49571
|
-
isKnownProjectVersionIntentType: () => isKnownProjectVersionIntentType
|
|
49572
|
-
});
|
|
49573
49794
|
function createProjectVersionIntent(type, details) {
|
|
49574
49795
|
if (details === void 0) {
|
|
49575
49796
|
return {
|
|
@@ -49588,24 +49809,6 @@ function isKnownProjectVersionIntentType(value) {
|
|
|
49588
49809
|
value
|
|
49589
49810
|
);
|
|
49590
49811
|
}
|
|
49591
|
-
function assertProjectVersionIntentIsKnown(intent) {
|
|
49592
|
-
if (!isKnownProjectVersionIntentType(intent.type)) {
|
|
49593
|
-
throw new Error(`Unknown project version intent type "${intent.type}".`);
|
|
49594
|
-
}
|
|
49595
|
-
if (intent.schemaVersion !== PROJECT_VERSION_INTENT_SCHEMA_VERSION) {
|
|
49596
|
-
throw new Error(
|
|
49597
|
-
`Project version intent "${intent.type}" uses schema version ${intent.schemaVersion}; expected ${PROJECT_VERSION_INTENT_SCHEMA_VERSION}.`
|
|
49598
|
-
);
|
|
49599
|
-
}
|
|
49600
|
-
}
|
|
49601
|
-
function assertProjectVersionIntentMatchesDiff(args) {
|
|
49602
|
-
assertProjectVersionIntentIsKnown(args.intent);
|
|
49603
|
-
if (args.diff.set === void 0 && args.diff.unset === void 0) {
|
|
49604
|
-
throw new Error(
|
|
49605
|
-
`Project version intent "${args.intent.type}" cannot be recorded with an empty diff.`
|
|
49606
|
-
);
|
|
49607
|
-
}
|
|
49608
|
-
}
|
|
49609
49812
|
var ProjectVersionIntentType, PROJECT_VERSION_INTENT_SCHEMA_VERSION;
|
|
49610
49813
|
var init_project_version_intents = __esm({
|
|
49611
49814
|
"../src/database/project-version-intents.ts"() {
|
|
@@ -62082,6 +62285,34 @@ var init_project_file_push = __esm({
|
|
|
62082
62285
|
}
|
|
62083
62286
|
});
|
|
62084
62287
|
|
|
62288
|
+
// src/commands/push-change-intent.ts
|
|
62289
|
+
function createNeoCliPushIntent(change) {
|
|
62290
|
+
const intentType = `${change.recordKind}.${change.kind}`;
|
|
62291
|
+
if (!isKnownProjectVersionIntentType(intentType)) {
|
|
62292
|
+
throw new Error(`No project version intent exists for "${intentType}".`);
|
|
62293
|
+
}
|
|
62294
|
+
if (change.recordKind !== "internal-record-relation") {
|
|
62295
|
+
return createProjectVersionIntent(intentType, { source: "neo-cli" });
|
|
62296
|
+
}
|
|
62297
|
+
const relationData = change.kind === "delete" ? change.baseData : change.nextData;
|
|
62298
|
+
if (!isInternalRecordRelation(relationData)) {
|
|
62299
|
+
throw new Error(
|
|
62300
|
+
`Cannot push internal record relation "${change.recordId}": ${change.kind} change has invalid relation data.`
|
|
62301
|
+
);
|
|
62302
|
+
}
|
|
62303
|
+
return createProjectVersionIntent(intentType, {
|
|
62304
|
+
source: "neo-cli",
|
|
62305
|
+
relationKind: relationData.relationKind
|
|
62306
|
+
});
|
|
62307
|
+
}
|
|
62308
|
+
var init_push_change_intent = __esm({
|
|
62309
|
+
"src/commands/push-change-intent.ts"() {
|
|
62310
|
+
"use strict";
|
|
62311
|
+
init_project_version_intents();
|
|
62312
|
+
init_project2();
|
|
62313
|
+
}
|
|
62314
|
+
});
|
|
62315
|
+
|
|
62085
62316
|
// src/commands/push.ts
|
|
62086
62317
|
var push_exports = {};
|
|
62087
62318
|
__export(push_exports, {
|
|
@@ -62736,22 +62967,13 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
|
|
|
62736
62967
|
{
|
|
62737
62968
|
operation: transactionOperation,
|
|
62738
62969
|
changes: status.changes.map((change) => {
|
|
62739
|
-
const intentType = `${change.recordKind}.${change.kind}`;
|
|
62740
|
-
if (!isKnownProjectVersionIntentType2(intentType)) {
|
|
62741
|
-
throw new Error(
|
|
62742
|
-
`No project version intent exists for "${intentType}".`
|
|
62743
|
-
);
|
|
62744
|
-
}
|
|
62745
62970
|
return {
|
|
62746
62971
|
recordKind: change.recordKind,
|
|
62747
62972
|
recordId: change.recordId,
|
|
62748
62973
|
operation: change.kind,
|
|
62749
62974
|
nextData: change.kind === "delete" ? void 0 : stripServerDerivedNeoScript(change.nextData),
|
|
62750
62975
|
deleted: change.kind === "delete" ? true : void 0,
|
|
62751
|
-
intent:
|
|
62752
|
-
intentType,
|
|
62753
|
-
{ source: "neo-cli" }
|
|
62754
|
-
),
|
|
62976
|
+
intent: createNeoCliPushIntent(change),
|
|
62755
62977
|
expectedBaseContentHash: change.kind === "create" ? null : change.casBaseHash ?? null
|
|
62756
62978
|
};
|
|
62757
62979
|
}),
|
|
@@ -62929,7 +63151,7 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
|
|
|
62929
63151
|
} catch (retryError) {
|
|
62930
63152
|
progress.stop();
|
|
62931
63153
|
if (retryError instanceof NeoApiError) {
|
|
62932
|
-
reportPushRejection(retryError.body);
|
|
63154
|
+
reportPushRejection(retryError.status, retryError.body);
|
|
62933
63155
|
process.exitCode = 1;
|
|
62934
63156
|
return;
|
|
62935
63157
|
}
|
|
@@ -62942,7 +63164,7 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
|
|
|
62942
63164
|
process.exitCode = 1;
|
|
62943
63165
|
return;
|
|
62944
63166
|
}
|
|
62945
|
-
reportPushRejection(rejection);
|
|
63167
|
+
reportPushRejection(error.status, rejection);
|
|
62946
63168
|
process.exitCode = 1;
|
|
62947
63169
|
return;
|
|
62948
63170
|
}
|
|
@@ -63064,7 +63286,7 @@ function stripServerDerivedNeoScript(value) {
|
|
|
63064
63286
|
if (next.kind === 23) delete next.action;
|
|
63065
63287
|
return next;
|
|
63066
63288
|
}
|
|
63067
|
-
function reportPushRejection(body) {
|
|
63289
|
+
function reportPushRejection(status, body) {
|
|
63068
63290
|
if (isObjectRecord2(body) && body.error === "base-hash-conflict") {
|
|
63069
63291
|
console.error(
|
|
63070
63292
|
'Push rejected: the server has newer state for these records. Run "neo pull" to merge, then push again.'
|
|
@@ -63091,7 +63313,7 @@ function reportPushRejection(body) {
|
|
|
63091
63313
|
);
|
|
63092
63314
|
return;
|
|
63093
63315
|
}
|
|
63094
|
-
console.error(`Push rejected (
|
|
63316
|
+
console.error(`Push rejected (${status}): ${JSON.stringify(body)}`);
|
|
63095
63317
|
}
|
|
63096
63318
|
function immediateTransactionId(result) {
|
|
63097
63319
|
if (!isObjectRecord2(result)) return null;
|
|
@@ -64064,7 +64286,7 @@ function compileMigrationAction(schema, migrationData) {
|
|
|
64064
64286
|
migrationContext: true
|
|
64065
64287
|
});
|
|
64066
64288
|
}
|
|
64067
|
-
var compileNSAction2, compileNSFunction2, compileNSGetter2, compileNSSetter2,
|
|
64289
|
+
var compileNSAction2, compileNSFunction2, compileNSGetter2, compileNSSetter2, ProjectTransactionInterruptedError, ProjectTransactionFailedError, PROJECT_TRANSACTION_POLL_DELAYS_MS;
|
|
64068
64290
|
var init_push = __esm({
|
|
64069
64291
|
"src/commands/push.ts"() {
|
|
64070
64292
|
"use strict";
|
|
@@ -64074,7 +64296,6 @@ var init_push = __esm({
|
|
|
64074
64296
|
init_document();
|
|
64075
64297
|
init_http();
|
|
64076
64298
|
init_ui();
|
|
64077
|
-
init_project_version_intents();
|
|
64078
64299
|
init_workspace();
|
|
64079
64300
|
init_project_documents();
|
|
64080
64301
|
init_workspace_status();
|
|
@@ -64084,8 +64305,8 @@ var init_push = __esm({
|
|
|
64084
64305
|
init_project_file_push();
|
|
64085
64306
|
init_project_manifest();
|
|
64086
64307
|
init_merge();
|
|
64308
|
+
init_push_change_intent();
|
|
64087
64309
|
({ compileNSAction: compileNSAction2, compileNSFunction: compileNSFunction2, compileNSGetter: compileNSGetter2, compileNSSetter: compileNSSetter2 } = compiler_adapter_exports);
|
|
64088
|
-
({ createProjectVersionIntent: createProjectVersionIntent2, isKnownProjectVersionIntentType: isKnownProjectVersionIntentType2 } = project_version_intents_exports);
|
|
64089
64310
|
ProjectTransactionInterruptedError = class extends Error {
|
|
64090
64311
|
constructor(transactionId) {
|
|
64091
64312
|
super(
|
package/package.json
CHANGED
|
@@ -205,6 +205,14 @@ declarations. Structurally owned descriptors and concrete generic bindings
|
|
|
205
205
|
derive their identities from stable owner roles; do not invent `@id`
|
|
206
206
|
annotations for them.
|
|
207
207
|
|
|
208
|
+
For world layer links, `NeoTileLayerLink` and `NeoObjectLayerLink` are abstract,
|
|
209
|
+
relation-free system bases. Instantiate a concrete project-authored descendant
|
|
210
|
+
that resolves exactly one `targetLayer` relation, declared directly or inherited
|
|
211
|
+
from a project-authored ancestor. The class relation is the complete binding:
|
|
212
|
+
native source emits no value-level target metadata, and link values carry no
|
|
213
|
+
second persistence representation. Painting and other world-content writes
|
|
214
|
+
never create or repair link targets.
|
|
215
|
+
|
|
208
216
|
## Root and authored values
|
|
209
217
|
|
|
210
218
|
`Root.neo` contains a compiler-owned envelope of this form:
|