@neocompose/cli 0.36.2 → 0.36.4
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,36 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.36.4] - 2026-08-19
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Keep computed static/root binding value identities derived from their member
|
|
8
|
+
ids, so post-push source rewriting never inserts an `@id` inside the
|
|
9
|
+
initializer expression.
|
|
10
|
+
- Validate assigned-id source rewriting during `neo push --dry-run`, and keep
|
|
11
|
+
materialized scalar bindings stable so a successful push is followed by a
|
|
12
|
+
clean `neo status` without changing the authored initializer expression.
|
|
13
|
+
|
|
14
|
+
## [0.36.3] - 2026-08-19
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Preserve nullable List and Dictionary entry declarations in persisted
|
|
19
|
+
compiler contexts, and keep abstract stored collection fields writable
|
|
20
|
+
through the concrete subclass storage that implements them. Indexed
|
|
21
|
+
`is`-pattern reads and writes such as `Stacks[index] = null` now agree in
|
|
22
|
+
source analysis, IntelliSense, `neo script check --all`, and push replay.
|
|
23
|
+
- Run `neo script check --all` against one locally reconstructed prospective
|
|
24
|
+
project document instead of fetching a stale server document through a
|
|
25
|
+
separate path. New records, managed files, dialogues, and stored bodies are
|
|
26
|
+
validated with the same source transaction visible to local member bodies.
|
|
27
|
+
- Compile canonical `Reference<NeoImage>(id: ...).Slice(...)` and
|
|
28
|
+
`Reference<NeoAudioClip>(id: ...)` file fallbacks when a pulled file has no
|
|
29
|
+
registry symbol, and accept `List.Repeat<T>(value, count)` when an explicit
|
|
30
|
+
entry type is needed for values such as `null`.
|
|
31
|
+
- Include same-transaction texture and audio import-template changes in the
|
|
32
|
+
prospective document before validating managed-file defaults.
|
|
33
|
+
|
|
3
34
|
## [0.36.2] - 2026-08-19
|
|
4
35
|
|
|
5
36
|
### Fixed
|
package/dist/neo.mjs
CHANGED
|
@@ -1278,6 +1278,12 @@ function neoScriptRegistryEntryType(typeName) {
|
|
|
1278
1278
|
}
|
|
1279
1279
|
return REGISTRY_ENTRY_TYPES[typeName] ?? null;
|
|
1280
1280
|
}
|
|
1281
|
+
function neoScriptRegistryReferenceType(entryTypeName) {
|
|
1282
|
+
for (const definition2 of Object.values(REGISTRY_ENTRY_TYPES)) {
|
|
1283
|
+
if (definition2.entryType === entryTypeName) return definition2.refType;
|
|
1284
|
+
}
|
|
1285
|
+
return null;
|
|
1286
|
+
}
|
|
1281
1287
|
function parameter(name, type) {
|
|
1282
1288
|
return { name, type };
|
|
1283
1289
|
}
|
|
@@ -11398,6 +11404,19 @@ var init_strict_resolver = __esm({
|
|
|
11398
11404
|
expression.pos
|
|
11399
11405
|
);
|
|
11400
11406
|
}
|
|
11407
|
+
if (isPrimitive(referencedType, "ImageRef") || isPrimitive(referencedType, "AudioClipRef")) {
|
|
11408
|
+
if (hasProvenanceArgument) {
|
|
11409
|
+
throw new CompileError(
|
|
11410
|
+
`Reference<${referenceTypeArgument.kind === "named" ? referenceTypeArgument.name : "file"}> does not support withProvenance because a project file reference is a file id, not a value-row reference.`,
|
|
11411
|
+
expression.pos
|
|
11412
|
+
);
|
|
11413
|
+
}
|
|
11414
|
+
return literal(
|
|
11415
|
+
referencedType,
|
|
11416
|
+
expression.args[0].value,
|
|
11417
|
+
this.project
|
|
11418
|
+
);
|
|
11419
|
+
}
|
|
11401
11420
|
return {
|
|
11402
11421
|
pointer: {
|
|
11403
11422
|
type: "reference" /* Reference */,
|
|
@@ -11407,6 +11426,37 @@ var init_strict_resolver = __esm({
|
|
|
11407
11426
|
type: referencedType
|
|
11408
11427
|
};
|
|
11409
11428
|
}
|
|
11429
|
+
if (expression.typeArguments && expression.callee.kind === "member" && expression.callee.receiver.kind === "ident" && expression.callee.receiver.name === NEOSCRIPT_LIST_TYPE_NAME) {
|
|
11430
|
+
if (expression.callee.name !== NEOSCRIPT_LIST_REPEAT_NAME) {
|
|
11431
|
+
throw new CompileError(
|
|
11432
|
+
`'${NEOSCRIPT_LIST_TYPE_NAME}' has no generic static member '${expression.callee.name}'.`,
|
|
11433
|
+
expression.pos
|
|
11434
|
+
);
|
|
11435
|
+
}
|
|
11436
|
+
if (expression.typeArguments.length !== 1) {
|
|
11437
|
+
throw new CompileError(
|
|
11438
|
+
`${NEOSCRIPT_LIST_TYPE_NAME}.${NEOSCRIPT_LIST_REPEAT_NAME}<T> requires exactly one entry type argument.`,
|
|
11439
|
+
expression.pos
|
|
11440
|
+
);
|
|
11441
|
+
}
|
|
11442
|
+
const entryTypeArgument = expression.typeArguments[0];
|
|
11443
|
+
if (entryTypeArgument === void 0) {
|
|
11444
|
+
throw new CompileError(
|
|
11445
|
+
`${NEOSCRIPT_LIST_TYPE_NAME}.${NEOSCRIPT_LIST_REPEAT_NAME}<T> requires exactly one entry type argument.`,
|
|
11446
|
+
expression.pos
|
|
11447
|
+
);
|
|
11448
|
+
}
|
|
11449
|
+
return this.resolveListStaticCall(
|
|
11450
|
+
expression.callee.name,
|
|
11451
|
+
expression.args,
|
|
11452
|
+
scope,
|
|
11453
|
+
{
|
|
11454
|
+
kind: "list",
|
|
11455
|
+
elementType: this.resolveType(entryTypeArgument)
|
|
11456
|
+
},
|
|
11457
|
+
expression.pos
|
|
11458
|
+
);
|
|
11459
|
+
}
|
|
11410
11460
|
if (expression.typeArguments) {
|
|
11411
11461
|
throw new CompileError(
|
|
11412
11462
|
"Generic intrinsic calls require a declaration-aware project source context.",
|
|
@@ -15209,11 +15259,17 @@ var init_strict_resolver = __esm({
|
|
|
15209
15259
|
*/
|
|
15210
15260
|
assertActionControlAccessible(action, operation, pos) {
|
|
15211
15261
|
const symbol = action.symbol;
|
|
15212
|
-
|
|
15213
|
-
|
|
15214
|
-
|
|
15215
|
-
|
|
15216
|
-
|
|
15262
|
+
let owner = symbol?.inheritedFrom ? this.project.typeById.get(symbol.inheritedFrom.typeId) : void 0;
|
|
15263
|
+
if (symbol !== void 0 && symbol.inheritedFrom === void 0) {
|
|
15264
|
+
for (const type of this.project.typeById.values()) {
|
|
15265
|
+
if (type.members.some(
|
|
15266
|
+
(candidate) => candidate.id === symbol.id && candidate.inheritedFrom === void 0
|
|
15267
|
+
)) {
|
|
15268
|
+
owner = type;
|
|
15269
|
+
break;
|
|
15270
|
+
}
|
|
15271
|
+
}
|
|
15272
|
+
}
|
|
15217
15273
|
if (symbol !== void 0 && owner !== void 0 && memberAccessFailure({
|
|
15218
15274
|
project: this.project,
|
|
15219
15275
|
context: this.context,
|
|
@@ -15535,6 +15591,11 @@ var init_strict_resolver = __esm({
|
|
|
15535
15591
|
resolved = { kind: "primitive", name: builtin };
|
|
15536
15592
|
break;
|
|
15537
15593
|
}
|
|
15594
|
+
const registryReference = neoScriptRegistryReferenceType(type.name);
|
|
15595
|
+
if (registryReference) {
|
|
15596
|
+
resolved = registryReference;
|
|
15597
|
+
break;
|
|
15598
|
+
}
|
|
15538
15599
|
const named = this.project.typeByName.get(type.name);
|
|
15539
15600
|
if (!named)
|
|
15540
15601
|
throw new CompileError(`Unknown type '${type.name}'`, type.pos);
|
|
@@ -32603,10 +32664,8 @@ function attachConstructorSignature(type, environment) {
|
|
|
32603
32664
|
type.id,
|
|
32604
32665
|
environment
|
|
32605
32666
|
);
|
|
32606
|
-
|
|
32607
|
-
(binding
|
|
32608
|
-
)) {
|
|
32609
|
-
return type;
|
|
32667
|
+
for (const binding of genericEnvironment.values()) {
|
|
32668
|
+
if (binding.kind === "unbound") return type;
|
|
32610
32669
|
}
|
|
32611
32670
|
const constructorSignature2 = buildNeoScriptConstructorSignature(
|
|
32612
32671
|
type.id,
|
|
@@ -32939,7 +32998,7 @@ function memberSymbol(member, schemaKey, environment, field) {
|
|
|
32939
32998
|
writable: false
|
|
32940
32999
|
};
|
|
32941
33000
|
}
|
|
32942
|
-
const writable = isReadOnly ? false : kind === "computed" ? computedHasSetter(member, field) :
|
|
33001
|
+
const writable = isReadOnly ? false : kind === "computed" ? computedHasSetter(member, field) : member.locked !== true;
|
|
32943
33002
|
const storage = typeof member.storage === "string" ? member.storage : void 0;
|
|
32944
33003
|
const writability = isReadOnly ? "readOnly" : kind === "computed" ? writable ? "setter" : "readOnly" : !writable ? "readOnly" : storage === "immutable" || storage === "save" || storage === "session" ? storage : isStatic && ownerClassId ? staticDefaultWritability(ownerClassId, environment) : void 0;
|
|
32945
33004
|
const lookupCollectionMemberId = kind === "lookup" ? string2(member.collectionMemberId, `${field}.collectionMemberId`) : null;
|
|
@@ -33475,9 +33534,12 @@ function memberType(member, environment, visiting, field) {
|
|
|
33475
33534
|
};
|
|
33476
33535
|
}
|
|
33477
33536
|
if (kind === "variant") {
|
|
33478
|
-
|
|
33479
|
-
|
|
33480
|
-
|
|
33537
|
+
let variantClass;
|
|
33538
|
+
for (const candidate of environment.classes.values()) {
|
|
33539
|
+
if (candidate.name !== NEO_VARIANT_TYPE_NAME) continue;
|
|
33540
|
+
variantClass = candidate;
|
|
33541
|
+
break;
|
|
33542
|
+
}
|
|
33481
33543
|
if (variantClass === void 0) return { ...unknownType(), nullable };
|
|
33482
33544
|
return {
|
|
33483
33545
|
kind: "named",
|
|
@@ -61766,7 +61828,8 @@ function interfaceToLanguageType(neoInterface, context) {
|
|
|
61766
61828
|
closure = [neoInterface];
|
|
61767
61829
|
}
|
|
61768
61830
|
const members = /* @__PURE__ */ new Map();
|
|
61769
|
-
for (
|
|
61831
|
+
for (let index = closure.length - 1; index >= 0; index -= 1) {
|
|
61832
|
+
const source = closure[index];
|
|
61770
61833
|
for (const key of getInterfaceMemberKeyOrder(source)) {
|
|
61771
61834
|
const member = source.members[key];
|
|
61772
61835
|
if (!member) continue;
|
|
@@ -62013,13 +62076,11 @@ function memberRuntimeType(record3, context, seen = /* @__PURE__ */ new Set(), g
|
|
|
62013
62076
|
const projectedEntry = entry ? substituteForGenericEnvironment(entry, genericEnvironment, context) : null;
|
|
62014
62077
|
return {
|
|
62015
62078
|
kind: "list",
|
|
62016
|
-
elementType: projectedEntry ?
|
|
62017
|
-
|
|
62018
|
-
|
|
62019
|
-
|
|
62020
|
-
|
|
62021
|
-
genericEnvironment
|
|
62022
|
-
)
|
|
62079
|
+
elementType: projectedEntry ? memberRuntimeType(
|
|
62080
|
+
projectedEntry,
|
|
62081
|
+
context,
|
|
62082
|
+
nextSeen,
|
|
62083
|
+
genericEnvironment
|
|
62023
62084
|
) : UNKNOWN_TYPE2,
|
|
62024
62085
|
listMemberId: record3.id,
|
|
62025
62086
|
nullable: !required2
|
|
@@ -62032,13 +62093,11 @@ function memberRuntimeType(record3, context, seen = /* @__PURE__ */ new Set(), g
|
|
|
62032
62093
|
return {
|
|
62033
62094
|
kind: "dictionary",
|
|
62034
62095
|
keyType: member.keyKind === "enum" && member.keyEnumId ? namedType(member.keyEnumId, true) : primitive2("string", true),
|
|
62035
|
-
valueType: projectedEntry ?
|
|
62036
|
-
|
|
62037
|
-
|
|
62038
|
-
|
|
62039
|
-
|
|
62040
|
-
genericEnvironment
|
|
62041
|
-
)
|
|
62096
|
+
valueType: projectedEntry ? memberRuntimeType(
|
|
62097
|
+
projectedEntry,
|
|
62098
|
+
context,
|
|
62099
|
+
nextSeen,
|
|
62100
|
+
genericEnvironment
|
|
62042
62101
|
) : UNKNOWN_TYPE2,
|
|
62043
62102
|
nullable: !required2
|
|
62044
62103
|
};
|
|
@@ -63037,7 +63096,10 @@ function initializerReferencesLexicalThis(source) {
|
|
|
63037
63096
|
}
|
|
63038
63097
|
function initializerReferencesAnyIdentifier(source, names) {
|
|
63039
63098
|
const identifiers = initializerReferencedIdentifiers(source);
|
|
63040
|
-
|
|
63099
|
+
for (const name of names) {
|
|
63100
|
+
if (identifiers.has(name)) return true;
|
|
63101
|
+
}
|
|
63102
|
+
return false;
|
|
63041
63103
|
}
|
|
63042
63104
|
function compileNSPropertyBodies(args) {
|
|
63043
63105
|
if (args.member.kind !== 10 /* NSProperty */) return;
|
|
@@ -63639,7 +63701,7 @@ function declaredConstructorsOfClass(constructors, schemaClass2) {
|
|
|
63639
63701
|
});
|
|
63640
63702
|
}
|
|
63641
63703
|
function argumentNameSetKey2(names) {
|
|
63642
|
-
return
|
|
63704
|
+
return names.map((name) => name.toLowerCase()).sort().join(", ");
|
|
63643
63705
|
}
|
|
63644
63706
|
function describeConstructorOverloads(constructors) {
|
|
63645
63707
|
return constructors.map(
|
|
@@ -63739,7 +63801,7 @@ function resolveMemberDeclaredTypeInfoInternal(member, members, seen) {
|
|
|
63739
63801
|
return {
|
|
63740
63802
|
type: resolved.kind,
|
|
63741
63803
|
required: resolved.required,
|
|
63742
|
-
entryTypeInfo
|
|
63804
|
+
entryTypeInfo,
|
|
63743
63805
|
...isMemberDictionaryBase(resolved) && resolved.keyEnumId ? { keyEnumId: resolved.keyEnumId } : {}
|
|
63744
63806
|
};
|
|
63745
63807
|
}
|
|
@@ -92000,7 +92062,12 @@ function materializeAuthoredListItems(args) {
|
|
|
92000
92062
|
args.member.entryMemberId
|
|
92001
92063
|
);
|
|
92002
92064
|
const unordered = listKindOf(args.member) === "unordered";
|
|
92003
|
-
const ids = unordered ? [
|
|
92065
|
+
const ids = unordered ? [] : args.row.value;
|
|
92066
|
+
if (unordered) {
|
|
92067
|
+
for (const row of args.authoredRows.values()) {
|
|
92068
|
+
if (row.containerId === args.row.id) ids.push(row.id);
|
|
92069
|
+
}
|
|
92070
|
+
}
|
|
92004
92071
|
const materializedIds = [];
|
|
92005
92072
|
for (const childId of ids) {
|
|
92006
92073
|
if (typeof childId !== "string") {
|
|
@@ -92259,6 +92326,12 @@ function initBackedValueRow(value) {
|
|
|
92259
92326
|
if (!isMemberValue(value)) return null;
|
|
92260
92327
|
return isInitValueContent(value) ? value : null;
|
|
92261
92328
|
}
|
|
92329
|
+
function valueIdsFromRows(explicitRows, sweepRows) {
|
|
92330
|
+
const ids = /* @__PURE__ */ new Set();
|
|
92331
|
+
for (const row of explicitRows) ids.add(row.id);
|
|
92332
|
+
for (const row of sweepRows) ids.add(row.id);
|
|
92333
|
+
return ids;
|
|
92334
|
+
}
|
|
92262
92335
|
function prepareServerOwnedValueInitializerBodies(args) {
|
|
92263
92336
|
const explicitRows = /* @__PURE__ */ new Map();
|
|
92264
92337
|
for (let index = 0; index < args.prepared.length; index += 1) {
|
|
@@ -92280,10 +92353,7 @@ function prepareServerOwnedValueInitializerBodies(args) {
|
|
|
92280
92353
|
args.postDocument,
|
|
92281
92354
|
args.prepared
|
|
92282
92355
|
);
|
|
92283
|
-
const targetIds =
|
|
92284
|
-
...[...explicitRows.values()].map((row) => row.id),
|
|
92285
|
-
...sweepRows.map((row) => row.id)
|
|
92286
|
-
]);
|
|
92356
|
+
const targetIds = valueIdsFromRows(explicitRows.values(), sweepRows);
|
|
92287
92357
|
const valuesById = new Map(
|
|
92288
92358
|
committedDocument.values.map((value) => [value.id, value])
|
|
92289
92359
|
);
|
|
@@ -92410,10 +92480,7 @@ function prepareServerOwnedDelegateValueBodies(args) {
|
|
|
92410
92480
|
args.postDocument,
|
|
92411
92481
|
args.prepared
|
|
92412
92482
|
);
|
|
92413
|
-
const targetIds =
|
|
92414
|
-
...[...explicitRows.values()].map((row) => row.id),
|
|
92415
|
-
...sweepRows.map((row) => row.id)
|
|
92416
|
-
]);
|
|
92483
|
+
const targetIds = valueIdsFromRows(explicitRows.values(), sweepRows);
|
|
92417
92484
|
const rootOwnerByValueId = /* @__PURE__ */ new Map();
|
|
92418
92485
|
const delegateScope = withVariantOwnershipRoots(
|
|
92419
92486
|
committedDocument,
|
|
@@ -92964,6 +93031,20 @@ function applyProjectVersionWriteChanges(document, changes) {
|
|
|
92964
93031
|
changes,
|
|
92965
93032
|
"project-file"
|
|
92966
93033
|
),
|
|
93034
|
+
// Import-setting templates are part of the same file graph. A new file
|
|
93035
|
+
// may select a new template in one source transaction, and default-value
|
|
93036
|
+
// materialization validates that relationship immediately against this
|
|
93037
|
+
// post-write document.
|
|
93038
|
+
textureTemplates: applyArrayChanges(
|
|
93039
|
+
document.textureTemplates ?? [],
|
|
93040
|
+
changes,
|
|
93041
|
+
"unity-texture-template"
|
|
93042
|
+
),
|
|
93043
|
+
audioClipTemplates: applyArrayChanges(
|
|
93044
|
+
document.audioClipTemplates ?? [],
|
|
93045
|
+
changes,
|
|
93046
|
+
"unity-audio-clip-template"
|
|
93047
|
+
),
|
|
92967
93048
|
internalRecordRelations: applyArrayChanges(
|
|
92968
93049
|
document.internalRecordRelations ?? [],
|
|
92969
93050
|
changes,
|
|
@@ -94884,7 +94965,7 @@ function listVirtualProjectSourceFilesV4(files) {
|
|
|
94884
94965
|
const kind = neoProjectSourceKind(file.path);
|
|
94885
94966
|
return kind !== null && isNeoProjectProductionSourceKind(kind) && !neoProjectPathHasIgnoredDirectory(file.path);
|
|
94886
94967
|
});
|
|
94887
|
-
const sorted =
|
|
94968
|
+
const sorted = selected.sort(
|
|
94888
94969
|
(left, right) => compareWorkspacePaths(left.path, right.path)
|
|
94889
94970
|
);
|
|
94890
94971
|
for (let index = 1; index < sorted.length; index += 1) {
|
|
@@ -95525,14 +95606,24 @@ function computeWorkspaceStatus(workspace, options) {
|
|
|
95525
95606
|
(binary) => binary.action !== "unchanged" && binary.action !== "converged"
|
|
95526
95607
|
);
|
|
95527
95608
|
reportPhase("binary-inspection");
|
|
95528
|
-
const invalidatedFileIds = /* @__PURE__ */ new Set(
|
|
95529
|
-
|
|
95530
|
-
|
|
95531
|
-
|
|
95532
|
-
|
|
95533
|
-
|
|
95609
|
+
const invalidatedFileIds = /* @__PURE__ */ new Set();
|
|
95610
|
+
for (const binary of binaryFiles) {
|
|
95611
|
+
if (binary.action === "create" || binary.action === "upload") {
|
|
95612
|
+
invalidatedFileIds.add(binary.fileId);
|
|
95613
|
+
}
|
|
95614
|
+
}
|
|
95615
|
+
for (const fileId of options.trustedPendingProjectFiles?.keys() ?? []) {
|
|
95616
|
+
invalidatedFileIds.add(fileId);
|
|
95617
|
+
}
|
|
95618
|
+
if (options.skipProjectBinaryInspection) {
|
|
95619
|
+
for (const record3 of reconstructed3.values()) {
|
|
95620
|
+
if (record3.recordKind === "project-file" && record3.fullData.status !== "uploaded") {
|
|
95621
|
+
invalidatedFileIds.add(record3.recordId);
|
|
95622
|
+
}
|
|
95623
|
+
}
|
|
95624
|
+
}
|
|
95534
95625
|
for (const message of validateFinalizedFileAssignmentsV4(
|
|
95535
|
-
|
|
95626
|
+
Array.from(reconstructed3.values(), (record3) => ({
|
|
95536
95627
|
recordKind: record3.recordKind,
|
|
95537
95628
|
data: record3.fullData
|
|
95538
95629
|
})),
|
|
@@ -95585,10 +95676,13 @@ function computeWorkspaceStatus(workspace, options) {
|
|
|
95585
95676
|
intent: createNeoCliPushIntent(change),
|
|
95586
95677
|
expectedBaseContentHash: change.kind === "create" ? null : change.casBaseHash ?? null
|
|
95587
95678
|
})),
|
|
95588
|
-
authoredValueSeeds:
|
|
95589
|
-
|
|
95590
|
-
|
|
95591
|
-
|
|
95679
|
+
authoredValueSeeds: Array.from(
|
|
95680
|
+
authoredValueSeeds,
|
|
95681
|
+
([memberId, seed]) => ({
|
|
95682
|
+
memberId,
|
|
95683
|
+
...seed
|
|
95684
|
+
})
|
|
95685
|
+
)
|
|
95592
95686
|
});
|
|
95593
95687
|
} catch (error) {
|
|
95594
95688
|
parseErrors.push(
|
|
@@ -95911,12 +96005,23 @@ function prospectiveAnimationRecords(base, reconstructed3, changes, seeds) {
|
|
|
95911
96005
|
const key = recordStateKey(change.recordKind, change.recordId);
|
|
95912
96006
|
if (change.kind === "delete") prospective.delete(key);
|
|
95913
96007
|
}
|
|
95914
|
-
|
|
95915
|
-
|
|
95916
|
-
|
|
95917
|
-
|
|
95918
|
-
|
|
95919
|
-
|
|
96008
|
+
let projectRecord;
|
|
96009
|
+
for (const record3 of prospective.values()) {
|
|
96010
|
+
if (record3.recordKind === "project") {
|
|
96011
|
+
projectRecord = record3;
|
|
96012
|
+
break;
|
|
96013
|
+
}
|
|
96014
|
+
}
|
|
96015
|
+
if (projectRecord === void 0) {
|
|
96016
|
+
for (const record3 of reconstructed3.values()) {
|
|
96017
|
+
if (record3.recordKind !== "project") continue;
|
|
96018
|
+
projectRecord = {
|
|
96019
|
+
recordKind: record3.recordKind,
|
|
96020
|
+
data: record3.fullData
|
|
96021
|
+
};
|
|
96022
|
+
break;
|
|
96023
|
+
}
|
|
96024
|
+
}
|
|
95920
96025
|
const projectId = projectRecord?.data.id;
|
|
95921
96026
|
const seedEnvelope = typeof projectId === "string" ? { projectId, createdAt: 0, updatedAt: 0 } : {};
|
|
95922
96027
|
for (const [key, record3] of reconstructed3) {
|
|
@@ -97317,43 +97422,47 @@ function compilePulledMemberInitializerBodyV4(document, memberId, compilationPro
|
|
|
97317
97422
|
}
|
|
97318
97423
|
function readPulledProjectDocumentV4(records2) {
|
|
97319
97424
|
const raw = structuredClone(
|
|
97320
|
-
pulledProjectDocumentRaw(
|
|
97321
|
-
|
|
97322
|
-
|
|
97323
|
-
completeProspectiveMemberCreateEnvelopes(
|
|
97324
|
-
completeProspectiveLocalizedTexts(raw)
|
|
97325
|
-
),
|
|
97326
|
-
{
|
|
97327
|
-
constructors: "authored-or-compiled",
|
|
97328
|
-
identities: "prospective",
|
|
97329
|
-
members: "authored-or-compiled"
|
|
97330
|
-
}
|
|
97425
|
+
pulledProjectDocumentRaw(
|
|
97426
|
+
replayWorkspace(completeProspectiveRecordCreateEnvelopes(records2))
|
|
97427
|
+
)
|
|
97331
97428
|
);
|
|
97429
|
+
return readProjectDocument(completeProspectiveLocalizedTexts(raw), {
|
|
97430
|
+
constructors: "authored-or-compiled",
|
|
97431
|
+
identities: "prospective",
|
|
97432
|
+
members: "authored-or-compiled"
|
|
97433
|
+
});
|
|
97332
97434
|
}
|
|
97333
|
-
function
|
|
97334
|
-
|
|
97335
|
-
|
|
97336
|
-
|
|
97337
|
-
|
|
97338
|
-
|
|
97435
|
+
function completeProspectiveRecordCreateEnvelopes(records2) {
|
|
97436
|
+
let project;
|
|
97437
|
+
for (const record3 of records2.values()) {
|
|
97438
|
+
if (!record3.deleted && record3.recordKind === "project" && isObjectRecord2(record3.data)) {
|
|
97439
|
+
project = record3;
|
|
97440
|
+
break;
|
|
97441
|
+
}
|
|
97442
|
+
}
|
|
97443
|
+
const projectId = isObjectRecord2(project?.data) ? project.data.id : null;
|
|
97444
|
+
if (typeof projectId !== "string") {
|
|
97339
97445
|
throw new Error(
|
|
97340
|
-
"
|
|
97446
|
+
"Prospective source-authored records need the server create envelope, but the project record has no id."
|
|
97341
97447
|
);
|
|
97342
97448
|
}
|
|
97343
|
-
|
|
97344
|
-
|
|
97345
|
-
|
|
97346
|
-
(
|
|
97347
|
-
|
|
97449
|
+
const completed = /* @__PURE__ */ new Map();
|
|
97450
|
+
for (const [key, record3] of records2) {
|
|
97451
|
+
if (record3.deleted || record3.recordKind === "project" || !isObjectRecord2(record3.data) || typeof record3.data.id !== "string" || typeof record3.data.projectId === "string" && typeof record3.data.createdAt === "number" && typeof record3.data.updatedAt === "number") {
|
|
97452
|
+
completed.set(key, record3);
|
|
97453
|
+
continue;
|
|
97454
|
+
}
|
|
97455
|
+
completed.set(key, {
|
|
97456
|
+
...record3,
|
|
97457
|
+
data: {
|
|
97458
|
+
projectId,
|
|
97348
97459
|
createdAt: 0,
|
|
97349
97460
|
updatedAt: 0,
|
|
97350
|
-
...
|
|
97351
|
-
}
|
|
97352
|
-
)
|
|
97353
|
-
}
|
|
97354
|
-
|
|
97355
|
-
function isPendingMemberWithoutCreateEnvelope(value) {
|
|
97356
|
-
return isObjectRecord2(value) && typeof value.id === "string" && value.id.startsWith("__pending__:") && (typeof value.projectId !== "string" || typeof value.createdAt !== "number" || typeof value.updatedAt !== "number");
|
|
97461
|
+
...record3.data
|
|
97462
|
+
}
|
|
97463
|
+
});
|
|
97464
|
+
}
|
|
97465
|
+
return completed;
|
|
97357
97466
|
}
|
|
97358
97467
|
function completeProspectiveLocalizedTexts(raw) {
|
|
97359
97468
|
const localizedTexts = raw.localizedTexts;
|
|
@@ -99545,7 +99654,7 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
|
|
|
99545
99654
|
`Value ${path} in ${source.label} writes @id(${JSON.stringify(unattachedId)}) on part of a computed expression rather than on the row. Parenthesize the expression so the annotation names the whole row.`
|
|
99546
99655
|
);
|
|
99547
99656
|
}
|
|
99548
|
-
if (annotated.id === null && isPendingId(valueId) && !context.pendingValueIdentitySites.has(valueId)) {
|
|
99657
|
+
if (annotated.id === null && isPendingId(valueId) && pendingMemberValueMemberId(valueId) === null && !context.pendingValueIdentitySites.has(valueId)) {
|
|
99549
99658
|
context.pendingValueIdentitySites.set(valueId, {
|
|
99550
99659
|
id: valueId,
|
|
99551
99660
|
uri: source.source.uri,
|
|
@@ -100149,6 +100258,16 @@ function lowerValueRow(context, member, sourceExpression, expectedValueId, sourc
|
|
|
100149
100258
|
}
|
|
100150
100259
|
indexInitAuthoredRowIds(context, code, source.label);
|
|
100151
100260
|
const storedConstructorArgs = isObjectRecord2(base.constructorArgs) ? base.constructorArgs : null;
|
|
100261
|
+
if (resolvedMember.kind !== "class" && isLiteralValueContent(base)) {
|
|
100262
|
+
addReconstructed(
|
|
100263
|
+
context,
|
|
100264
|
+
"value",
|
|
100265
|
+
expectedValueId,
|
|
100266
|
+
valueFileFields(base),
|
|
100267
|
+
source.source
|
|
100268
|
+
);
|
|
100269
|
+
return expectedValueId;
|
|
100270
|
+
}
|
|
100152
100271
|
const materializedClass = resolvedMember.kind === "class" && isObjectRecord2(base.value);
|
|
100153
100272
|
const effectiveClassId = resolvedMember.kind === "class" ? stringOrNull(base.classId) ?? resolvedMember.classId : null;
|
|
100154
100273
|
const materializedPlainClass = materializedClass && effectiveClassId !== null && context.classes.get(effectiveClassId)?.requiredConstructorId === void 0;
|
|
@@ -109225,7 +109344,7 @@ function qualifiedMemberLabel(thisClass, member) {
|
|
|
109225
109344
|
if (typeof thisClass.name !== "string") return `'${memberName}'`;
|
|
109226
109345
|
return `'${thisClass.name}.${memberName}'`;
|
|
109227
109346
|
}
|
|
109228
|
-
function
|
|
109347
|
+
function analyzeWorkspaceProjectV4(workspace) {
|
|
109229
109348
|
const status = computeWorkspaceStatus2(workspace, {
|
|
109230
109349
|
skipProjectBinaryInspection: true
|
|
109231
109350
|
});
|
|
@@ -109250,13 +109369,35 @@ ${blockingErrors.map((error) => ` ${error.message}`).join("\n")}`
|
|
|
109250
109369
|
data: record3.fullData
|
|
109251
109370
|
});
|
|
109252
109371
|
}
|
|
109253
|
-
|
|
109372
|
+
const records2 = /* @__PURE__ */ new Map();
|
|
109373
|
+
for (const record3 of status.reconstructed.values()) {
|
|
109374
|
+
records2.set(`${record3.recordKind}:${record3.recordId}`, {
|
|
109375
|
+
recordKind: record3.recordKind,
|
|
109376
|
+
recordId: record3.recordId,
|
|
109377
|
+
contentHash: "local-script-check",
|
|
109378
|
+
deleted: false,
|
|
109379
|
+
data: record3.fullData
|
|
109380
|
+
});
|
|
109381
|
+
}
|
|
109382
|
+
return {
|
|
109383
|
+
manifest: documentsToProjectSchemaManifest(documents),
|
|
109384
|
+
document: readDocumentArrays(
|
|
109385
|
+
readPulledProjectDocumentV4(records2)
|
|
109386
|
+
)
|
|
109387
|
+
};
|
|
109254
109388
|
}
|
|
109255
109389
|
async function runScript(workspace, command, options, dependencies = {}) {
|
|
109256
109390
|
let localCheckManifest = null;
|
|
109391
|
+
let localCheckDocument = null;
|
|
109257
109392
|
const targetsLocalMember = (command === "check" || command === "compile") && options.memberRef !== null;
|
|
109258
109393
|
if (command === "check" && options.all || targetsLocalMember) {
|
|
109259
|
-
|
|
109394
|
+
if (dependencies.analyzeWorkspaceManifest === void 0) {
|
|
109395
|
+
const localProject = analyzeWorkspaceProjectV4(workspace);
|
|
109396
|
+
localCheckManifest = localProject.manifest;
|
|
109397
|
+
localCheckDocument = localProject.document;
|
|
109398
|
+
} else {
|
|
109399
|
+
localCheckManifest = dependencies.analyzeWorkspaceManifest(workspace);
|
|
109400
|
+
}
|
|
109260
109401
|
if (targetsLocalMember) {
|
|
109261
109402
|
const localTarget = resolveLocalScriptMember(
|
|
109262
109403
|
localCheckManifest,
|
|
@@ -109276,6 +109417,10 @@ async function runScript(workspace, command, options, dependencies = {}) {
|
|
|
109276
109417
|
return;
|
|
109277
109418
|
}
|
|
109278
109419
|
}
|
|
109420
|
+
if (command === "check" && options.all && localCheckManifest !== null && localCheckDocument !== null) {
|
|
109421
|
+
runCheckAll(localCheckDocument, localCheckManifest, options);
|
|
109422
|
+
return;
|
|
109423
|
+
}
|
|
109279
109424
|
const client = NeoApiClient.forBaseUrl(workspace.config.apiBaseUrl);
|
|
109280
109425
|
const { raw } = await fetchProjectDocument(workspace);
|
|
109281
109426
|
const document = readDocumentArrays(raw);
|
|
@@ -110219,6 +110364,7 @@ var init_script = __esm({
|
|
|
110219
110364
|
init_workspace_status();
|
|
110220
110365
|
init_source_diagnostics();
|
|
110221
110366
|
init_project_documents();
|
|
110367
|
+
init_initializer_replay();
|
|
110222
110368
|
init_push_body_diagnostics();
|
|
110223
110369
|
RETURN_SHORTHANDS = {
|
|
110224
110370
|
// MemberKind numerics: Bool=1, Int=2, String=3, Float=4.
|
|
@@ -112217,6 +112363,13 @@ async function prepareLocalPushArtifactsV4(workspace, status, onPhase = () => vo
|
|
|
112217
112363
|
);
|
|
112218
112364
|
let preparedChanges = null;
|
|
112219
112365
|
if (options.fullValidation) {
|
|
112366
|
+
onPhase("Verifying the assigned-id source rewrite\u2026");
|
|
112367
|
+
materializeAssignedSchemaIdsInAuthoredSource(
|
|
112368
|
+
workspace,
|
|
112369
|
+
pendingAssignment.assigned,
|
|
112370
|
+
status.pendingValueIdentitySites,
|
|
112371
|
+
true
|
|
112372
|
+
);
|
|
112220
112373
|
onPhase("Verifying the complete source round trip\u2026");
|
|
112221
112374
|
verifyProjectSourceCommitAgainstStateV4({
|
|
112222
112375
|
projectId: workspace.config.projectId,
|
|
@@ -113046,17 +113199,7 @@ function rewriteFilesFromState(workspace, records2 = new Map(
|
|
|
113046
113199
|
return { uri: file.path, kind, text: file.content };
|
|
113047
113200
|
})
|
|
113048
113201
|
);
|
|
113049
|
-
|
|
113050
|
-
(diagnostic) => diagnostic.severity === "error" && !isPullRecoveryDiagnosticCode(diagnostic.code)
|
|
113051
|
-
);
|
|
113052
|
-
if (finalErrors.length > 0) {
|
|
113053
|
-
throw new Error(
|
|
113054
|
-
`Assigned-id source rewrite produced invalid source:
|
|
113055
|
-
${finalErrors.map(
|
|
113056
|
-
(diagnostic) => ` ${diagnostic.uri}:${diagnostic.range.start.line + 1}:${diagnostic.range.start.character + 1} ${diagnostic.message}`
|
|
113057
|
-
).join("\n")}`
|
|
113058
|
-
);
|
|
113059
|
-
}
|
|
113202
|
+
assertAssignedIdSourceRewriteValid(finalAnalysis);
|
|
113060
113203
|
writeProjectSourceAnalysisCacheV4(workspace.root, finalAnalysis);
|
|
113061
113204
|
const emittedPaths = new Set(files.map((file) => file.path));
|
|
113062
113205
|
for (const recordState of Object.values(workspace.state.records)) {
|
|
@@ -113082,7 +113225,20 @@ ${finalErrors.map(
|
|
|
113082
113225
|
workspace.state.records[key] = nextState;
|
|
113083
113226
|
}
|
|
113084
113227
|
}
|
|
113085
|
-
function
|
|
113228
|
+
function assertAssignedIdSourceRewriteValid(analysis) {
|
|
113229
|
+
const finalErrors = analysis.diagnostics.filter(
|
|
113230
|
+
(diagnostic) => diagnostic.severity === "error" && !isPullRecoveryDiagnosticCode(diagnostic.code)
|
|
113231
|
+
);
|
|
113232
|
+
if (finalErrors.length > 0) {
|
|
113233
|
+
throw new Error(
|
|
113234
|
+
`Assigned-id source rewrite produced invalid source:
|
|
113235
|
+
${finalErrors.map(
|
|
113236
|
+
(diagnostic) => ` ${diagnostic.uri}:${diagnostic.range.start.line + 1}:${diagnostic.range.start.character + 1} ${diagnostic.message}`
|
|
113237
|
+
).join("\n")}`
|
|
113238
|
+
);
|
|
113239
|
+
}
|
|
113240
|
+
}
|
|
113241
|
+
function materializeAssignedSchemaIdsInAuthoredSource(workspace, replacements, pendingValueIdentitySites = /* @__PURE__ */ new Map(), validateResult = false) {
|
|
113086
113242
|
const pendingIdsByUri = /* @__PURE__ */ new Map();
|
|
113087
113243
|
for (const pendingId2 of replacements.keys()) {
|
|
113088
113244
|
if (!isPendingId(pendingId2)) continue;
|
|
@@ -113258,6 +113414,16 @@ function materializeAssignedSchemaIdsInAuthoredSource(workspace, replacements, p
|
|
|
113258
113414
|
}
|
|
113259
113415
|
preserved.set(uri, source);
|
|
113260
113416
|
}
|
|
113417
|
+
if (validateResult && preserved.size > 0) {
|
|
113418
|
+
assertAssignedIdSourceRewriteValid(
|
|
113419
|
+
compileNeoProjectSources(
|
|
113420
|
+
inputs.map((input) => ({
|
|
113421
|
+
...input,
|
|
113422
|
+
text: preserved.get(input.uri) ?? input.text
|
|
113423
|
+
}))
|
|
113424
|
+
)
|
|
113425
|
+
);
|
|
113426
|
+
}
|
|
113261
113427
|
return preserved;
|
|
113262
113428
|
}
|
|
113263
113429
|
function sourceOffsetInsideInitializer(source, oneBasedLine, oneBasedColumn) {
|
|
@@ -113874,7 +114040,7 @@ var init_registry2 = __esm({
|
|
|
113874
114040
|
PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
113875
114041
|
formatVersion: 3,
|
|
113876
114042
|
contractVersion: "3.14",
|
|
113877
|
-
cliVersion: "0.36.
|
|
114043
|
+
cliVersion: "0.36.4",
|
|
113878
114044
|
projectFileUploadBatchSize: 32,
|
|
113879
114045
|
documentRecords: {
|
|
113880
114046
|
member: {
|
|
@@ -120476,7 +120642,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
|
|
|
120476
120642
|
async function main() {
|
|
120477
120643
|
const args = parseArgs(process.argv.slice(2));
|
|
120478
120644
|
if (args.command === "--version") {
|
|
120479
|
-
console.log("0.36.
|
|
120645
|
+
console.log("0.36.4");
|
|
120480
120646
|
return;
|
|
120481
120647
|
}
|
|
120482
120648
|
if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
|
package/package.json
CHANGED
|
@@ -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.36.
|
|
86
|
+
<!-- reviewed-through-cli: 0.36.4 -->
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
The quoted version above is checked too, so this instruction cannot go stale
|
|
@@ -78,6 +78,11 @@ neo script eval --function Outpost.RefreshUnlock --this-value <id> --args '[3]'
|
|
|
78
78
|
|
|
79
79
|
Prefer `--json` for automation.
|
|
80
80
|
|
|
81
|
+
`neo script check --all` reconstructs the prospective project entirely from
|
|
82
|
+
the local workspace. It checks local schema bodies and stored dialogue,
|
|
83
|
+
migration, and text-variable bodies against that same source transaction, so
|
|
84
|
+
new declarations do not depend on a prior push or a network fetch.
|
|
85
|
+
|
|
81
86
|
Inside an inline Class body, unqualified names resolve against that Class;
|
|
82
87
|
invoke delegate and action members directly with `Selector()` or `OnChanged()`.
|
|
83
88
|
Spell a zero-argument action as bare `NeoAction`; type arguments name action
|
|
@@ -196,11 +201,13 @@ instead of hand-counting a literal or looping around `Add`:
|
|
|
196
201
|
List<int> scores = List.Repeat(0, 10);
|
|
197
202
|
```
|
|
198
203
|
|
|
199
|
-
The entry type is inferred from the value and joined with the
|
|
200
|
-
context, exactly like a list literal, so assigning
|
|
201
|
-
`List<float>` widens the entries to `float`.
|
|
202
|
-
|
|
203
|
-
|
|
204
|
+
The entry type is normally inferred from the value and joined with the
|
|
205
|
+
assignment context, exactly like a list literal, so assigning
|
|
206
|
+
`List.Repeat(0, 4)` to a `List<float>` widens the entries to `float`. When the
|
|
207
|
+
value cannot carry the type by itself, use a call-site type argument, for
|
|
208
|
+
example `List.Repeat<InventoryItemStack?>(null, slotCount)`. Never spell type
|
|
209
|
+
arguments on the qualifier: `List<int>.Repeat(0, 3)` is an error, and bare
|
|
210
|
+
`List` is a qualifier, not a value.
|
|
204
211
|
|
|
205
212
|
`count` must be an `int` — a `float` count is a compile error, and a negative
|
|
206
213
|
count fails at runtime with `List.Repeat count must be non-negative; got
|