@neocompose/cli 0.48.1 → 0.48.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,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.48.3] - 2026-09-10
|
|
4
|
+
|
|
5
|
+
- Show inherited generic binding defaults in implicit constructions, so sparse
|
|
6
|
+
instances expose their effective values and no longer warn about unsettled
|
|
7
|
+
required members. Matching defaults remain virtual through pull/status and
|
|
8
|
+
edits create ordinary sparse overrides. Recorded constructors keep their
|
|
9
|
+
own settlement behavior.
|
|
10
|
+
- Preserve hidden collection argument defaults and ordering when lowering
|
|
11
|
+
unchanged generic types.
|
|
12
|
+
|
|
13
|
+
## [0.48.2] - 2026-09-10
|
|
14
|
+
|
|
15
|
+
- Emit class member defaults with contextual `new()` when they construct the declared type, while keeping an explicit concrete type for subclass defaults.
|
|
16
|
+
|
|
3
17
|
## [0.48.1] - 2026-09-10
|
|
4
18
|
|
|
5
19
|
- Emit empty class member defaults as `new Type()` even when their backing value row is virtual. Required members now read as initialized, and adding a `new() { ... }` override preserves sparse storage.
|
package/dist/neo.mjs
CHANGED
|
@@ -64603,6 +64603,22 @@ function manifestTypeForMember(context, member) {
|
|
|
64603
64603
|
}
|
|
64604
64604
|
return primitive3;
|
|
64605
64605
|
}
|
|
64606
|
+
if (member.kind === "list" || member.kind === "dictionary") {
|
|
64607
|
+
const entry = context.baseMembers.get(member.entryMemberId);
|
|
64608
|
+
if (entry === void 0)
|
|
64609
|
+
throw new Error(
|
|
64610
|
+
`Collection ${member.name} has no entry member ${member.entryMemberId}.`
|
|
64611
|
+
);
|
|
64612
|
+
const entryType = manifestTypeForMember(context, entry);
|
|
64613
|
+
if (member.kind === "list")
|
|
64614
|
+
return { name: "List", nullable: nullable2, arguments: [entryType] };
|
|
64615
|
+
const keyType = {
|
|
64616
|
+
name: member.key.kind === "string" ? "string" : context.baseEnums.get(member.key.enumId)?.name ?? "object",
|
|
64617
|
+
nullable: false,
|
|
64618
|
+
arguments: []
|
|
64619
|
+
};
|
|
64620
|
+
return { name: "Dictionary", nullable: nullable2, arguments: [keyType, entryType] };
|
|
64621
|
+
}
|
|
64606
64622
|
if (member.kind === "class") {
|
|
64607
64623
|
const schemaClass2 = context.baseClasses.get(member.classId);
|
|
64608
64624
|
const classType = {
|
|
@@ -64848,6 +64864,16 @@ function lowerGenericArgument(context, ownerClass, type, memberId, genericParamI
|
|
|
64848
64864
|
const base = context.baseMembers.get(memberId);
|
|
64849
64865
|
if (base && JSON.stringify(manifestTypeForMember(context, base)) === JSON.stringify(type)) {
|
|
64850
64866
|
context.loweredMembers.set(memberId, { ...base, owner });
|
|
64867
|
+
if (base.kind === "list" || base.kind === "dictionary") {
|
|
64868
|
+
lowerCollectionEntry(
|
|
64869
|
+
context,
|
|
64870
|
+
ownerClass,
|
|
64871
|
+
requiredTypeArgument(type, base.kind === "list" ? 0 : 1),
|
|
64872
|
+
base.entryMemberId,
|
|
64873
|
+
memberId,
|
|
64874
|
+
memberId
|
|
64875
|
+
);
|
|
64876
|
+
}
|
|
64851
64877
|
return;
|
|
64852
64878
|
}
|
|
64853
64879
|
const declaration = {
|
|
@@ -113263,6 +113289,7 @@ function buildValueEmitContext(records2, manifest) {
|
|
|
113263
113289
|
},
|
|
113264
113290
|
members,
|
|
113265
113291
|
classes,
|
|
113292
|
+
implicitGenericMembersByClassId: /* @__PURE__ */ new Map(),
|
|
113266
113293
|
manifestMembers,
|
|
113267
113294
|
manifestClasses: new Map(
|
|
113268
113295
|
manifest.classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
|
|
@@ -113680,9 +113707,7 @@ function emitMemberDefaultSourcesV4(records2, manifest) {
|
|
|
113680
113707
|
member,
|
|
113681
113708
|
{ classId: defaultValue.classId ?? null, value: backed.body },
|
|
113682
113709
|
visited,
|
|
113683
|
-
(defaultValue.classId ?? member.classId) === member.classId && manifestMember?.kind === "class"
|
|
113684
|
-
(argument2) => argument2.kind === "generic"
|
|
113685
|
-
),
|
|
113710
|
+
(defaultValue.classId ?? member.classId) === member.classId && manifestMember?.kind === "class",
|
|
113686
113711
|
environment
|
|
113687
113712
|
);
|
|
113688
113713
|
} else if (backed.kind === "list") {
|
|
@@ -116499,18 +116524,32 @@ function lowerClassValue(context, member, expression, base, source, outerEnviron
|
|
|
116499
116524
|
`Class value ${String(base.id)}.${assignment.name} cannot place existing value ${symbolId2} into a new structural slot. Create the nested value inline so the atomic construction transaction can own it.`
|
|
116500
116525
|
);
|
|
116501
116526
|
}
|
|
116502
|
-
|
|
116527
|
+
const rows = /* @__PURE__ */ new Map();
|
|
116528
|
+
const localizedTexts = /* @__PURE__ */ new Map();
|
|
116529
|
+
const seededId = lowerSeedChild(
|
|
116503
116530
|
context,
|
|
116504
116531
|
recursivePartialMember(member, childMember),
|
|
116505
116532
|
assignment.value,
|
|
116506
116533
|
source,
|
|
116507
116534
|
`${String(base.id)}.${assignment.name}`,
|
|
116508
|
-
|
|
116509
|
-
|
|
116535
|
+
rows,
|
|
116536
|
+
localizedTexts,
|
|
116510
116537
|
void 0,
|
|
116511
116538
|
environment,
|
|
116512
116539
|
assignmentSlices.get(assignment.name)
|
|
116513
116540
|
);
|
|
116541
|
+
if (!partial && freshChildReplaysDeclaredDefault({
|
|
116542
|
+
context,
|
|
116543
|
+
childMember,
|
|
116544
|
+
childId: seededId,
|
|
116545
|
+
rows,
|
|
116546
|
+
localizedTexts,
|
|
116547
|
+
environment
|
|
116548
|
+
})) {
|
|
116549
|
+
deleteSeedRow(context, rows, seededId);
|
|
116550
|
+
continue;
|
|
116551
|
+
}
|
|
116552
|
+
body[assignment.name] = seededId;
|
|
116514
116553
|
continue;
|
|
116515
116554
|
}
|
|
116516
116555
|
const symbolId = sourceValueSymbol(context, assignment.value);
|
|
@@ -118311,23 +118350,33 @@ function freshChildReplaysDeclaredDefault(args) {
|
|
|
118311
118350
|
if (child.instanceVariantId != null) return false;
|
|
118312
118351
|
if (child.instanceVariantRowValueId != null) return false;
|
|
118313
118352
|
if (context.collectionBindingMemberIds.has(childMember.id)) return false;
|
|
118314
|
-
const defaultValue = childMember.defaultValue;
|
|
118315
|
-
if (defaultValue === null || defaultValue === void 0) return false;
|
|
118316
|
-
if (!("value" in defaultValue)) return false;
|
|
118317
118353
|
const resolved = resolveGenericSchemaMember(
|
|
118318
118354
|
context,
|
|
118319
118355
|
childMember,
|
|
118320
118356
|
environment
|
|
118321
118357
|
);
|
|
118358
|
+
let defaultValue = null;
|
|
118359
|
+
if (resolved.defaultValue && "value" in resolved.defaultValue) {
|
|
118360
|
+
defaultValue = resolved.defaultValue;
|
|
118361
|
+
} else if (resolved.defaultValue && "serverValueId" in resolved.defaultValue) {
|
|
118362
|
+
const storedMember = context.state[`member:${resolved.id}`]?.data;
|
|
118363
|
+
const storedDefault = isObjectRecord2(storedMember) ? storedMember.defaultValue : null;
|
|
118364
|
+
if (isObjectRecord2(storedDefault) && "value" in storedDefault) {
|
|
118365
|
+
defaultValue = {
|
|
118366
|
+
value: storedDefault.value,
|
|
118367
|
+
classId: storedDefault.classId
|
|
118368
|
+
};
|
|
118369
|
+
}
|
|
118370
|
+
}
|
|
118371
|
+
if (defaultValue === null) return false;
|
|
118322
118372
|
if (resolved.kind === "lookup" || resolved.kind === "dialogueLookup") {
|
|
118323
118373
|
return false;
|
|
118324
118374
|
}
|
|
118325
118375
|
if (resolved.kind === "class") {
|
|
118326
|
-
return freshConstructionReplaysDeclaredDefault(
|
|
118327
|
-
|
|
118328
|
-
|
|
118329
|
-
|
|
118330
|
-
);
|
|
118376
|
+
return freshConstructionReplaysDeclaredDefault(resolved, child, {
|
|
118377
|
+
value: defaultValue.value,
|
|
118378
|
+
classId: defaultValue.classId
|
|
118379
|
+
});
|
|
118331
118380
|
}
|
|
118332
118381
|
if (resolved.kind === "list") {
|
|
118333
118382
|
return Array.isArray(child.value) && child.value.length === 0 && !context.pendingContainerChildCounts.has(childId) && Array.isArray(defaultValue.value) && defaultValue.value.length === 0 && child.classId == null && (child.constructorArgs == null || Object.keys(child.constructorArgs).length === 0) && child.instanceConstructorId == null;
|
|
@@ -118905,6 +118954,41 @@ function classValue(context, member, value, visited, targetTyped, outerEnvironme
|
|
|
118905
118954
|
);
|
|
118906
118955
|
overrideKeys.add(key);
|
|
118907
118956
|
}
|
|
118957
|
+
if (!partial && value.instanceVariantId == null && value.instanceVariantRowValueId == null) {
|
|
118958
|
+
for (const [key, genericMember] of implicitGenericMembers(
|
|
118959
|
+
context,
|
|
118960
|
+
classId
|
|
118961
|
+
)) {
|
|
118962
|
+
if (key in value.value) continue;
|
|
118963
|
+
const parameterId = stringField3(genericMember, "genericParamId");
|
|
118964
|
+
if (!environment.has(parameterId)) continue;
|
|
118965
|
+
const binding = resolveGenericValueMember(
|
|
118966
|
+
context,
|
|
118967
|
+
genericMember,
|
|
118968
|
+
environment
|
|
118969
|
+
);
|
|
118970
|
+
const kind = numberField(binding, "kind");
|
|
118971
|
+
if (!IMPLICIT_GENERIC_DEFAULT_KINDS.has(kind)) continue;
|
|
118972
|
+
if (kind === 3 /* String */ && isLocalizedStringMember(binding))
|
|
118973
|
+
continue;
|
|
118974
|
+
if (binding.payload === 1 /* Partial */) continue;
|
|
118975
|
+
const defaultValue = binding.defaultValue;
|
|
118976
|
+
if (!isObjectRecord2(defaultValue) || !("value" in defaultValue)) continue;
|
|
118977
|
+
const body = defaultValue.value;
|
|
118978
|
+
if (body === null) continue;
|
|
118979
|
+
if (Array.isArray(body) && body.length > 0) continue;
|
|
118980
|
+
if (isObjectRecord2(body) && Object.keys(body).length > 0) continue;
|
|
118981
|
+
const expression = emitValueBody(
|
|
118982
|
+
context,
|
|
118983
|
+
binding,
|
|
118984
|
+
defaultValue,
|
|
118985
|
+
/* @__PURE__ */ new Set(),
|
|
118986
|
+
(defaultValue.classId ?? binding.classId) === binding.classId,
|
|
118987
|
+
environment
|
|
118988
|
+
);
|
|
118989
|
+
fields.push(`${key} = ${expression}`);
|
|
118990
|
+
}
|
|
118991
|
+
}
|
|
118908
118992
|
if (partial) {
|
|
118909
118993
|
return fields.length === 0 ? "new { }" : `new {
|
|
118910
118994
|
${fields.map((field) => indentNeoSourceNonEmptyLines(field, 2)).join(",\n")}
|
|
@@ -118923,6 +119007,33 @@ ${fields.map((field) => indentNeoSourceNonEmptyLines(field, 2)).join(",\n")}
|
|
|
118923
119007
|
${fields.map((field) => indentNeoSourceNonEmptyLines(field, 2)).join(",\n")}
|
|
118924
119008
|
}`;
|
|
118925
119009
|
}
|
|
119010
|
+
function implicitGenericMembers(context, classId) {
|
|
119011
|
+
const cached = context.implicitGenericMembersByClassId.get(classId);
|
|
119012
|
+
if (cached !== void 0) return cached;
|
|
119013
|
+
const result = /* @__PURE__ */ new Map();
|
|
119014
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
119015
|
+
const seenClasses = /* @__PURE__ */ new Set();
|
|
119016
|
+
let current = context.manifestClasses.get(classId);
|
|
119017
|
+
while (current !== void 0 && !seenClasses.has(current.id)) {
|
|
119018
|
+
seenClasses.add(current.id);
|
|
119019
|
+
if (current.requiredConstructorId || current.constructorIds?.length) {
|
|
119020
|
+
result.clear();
|
|
119021
|
+
context.implicitGenericMembersByClassId.set(classId, result);
|
|
119022
|
+
return result;
|
|
119023
|
+
}
|
|
119024
|
+
for (const [key, memberId] of Object.entries(current.schema)) {
|
|
119025
|
+
if (seenKeys.has(key)) continue;
|
|
119026
|
+
seenKeys.add(key);
|
|
119027
|
+
const member = context.members.get(memberId);
|
|
119028
|
+
if (member?.kind === 21 /* Generic */ && !isObjectRecord2(member.init)) {
|
|
119029
|
+
result.set(key, member);
|
|
119030
|
+
}
|
|
119031
|
+
}
|
|
119032
|
+
current = current.extendsClassId === null ? void 0 : context.manifestClasses.get(current.extendsClassId);
|
|
119033
|
+
}
|
|
119034
|
+
context.implicitGenericMembersByClassId.set(classId, result);
|
|
119035
|
+
return result;
|
|
119036
|
+
}
|
|
118926
119037
|
function emitsAsMemberDefaultDerivedAbsence(context, member, valueId) {
|
|
118927
119038
|
const value = context.values.get(valueId);
|
|
118928
119039
|
if (value === void 0) return false;
|
|
@@ -120458,7 +120569,7 @@ function memberDefaultBody(member) {
|
|
|
120458
120569
|
if (!("value" in defaultValue)) return null;
|
|
120459
120570
|
return defaultValue.value;
|
|
120460
120571
|
}
|
|
120461
|
-
var INFERRED_GENERIC_CLASS_PREFIX, MEMBER_KIND_DICTIONARY2, MEMBER_KIND_LIST2, MEMBER_KIND_CLASS2, LEADING_AUTHORED_ROW_ID, CANONICAL_CONSTRUCTOR_INLINE_WIDTH;
|
|
120572
|
+
var INFERRED_GENERIC_CLASS_PREFIX, MEMBER_KIND_DICTIONARY2, MEMBER_KIND_LIST2, MEMBER_KIND_CLASS2, IMPLICIT_GENERIC_DEFAULT_KINDS, LEADING_AUTHORED_ROW_ID, CANONICAL_CONSTRUCTOR_INLINE_WIDTH;
|
|
120462
120573
|
var init_value_sources = __esm({
|
|
120463
120574
|
"src/project-source/value-sources.ts"() {
|
|
120464
120575
|
"use strict";
|
|
@@ -120498,6 +120609,16 @@ var init_value_sources = __esm({
|
|
|
120498
120609
|
MEMBER_KIND_DICTIONARY2 = 5;
|
|
120499
120610
|
MEMBER_KIND_LIST2 = 6;
|
|
120500
120611
|
MEMBER_KIND_CLASS2 = 7;
|
|
120612
|
+
IMPLICIT_GENERIC_DEFAULT_KINDS = /* @__PURE__ */ new Set([
|
|
120613
|
+
1 /* Bool */,
|
|
120614
|
+
2 /* Int */,
|
|
120615
|
+
4 /* Float */,
|
|
120616
|
+
20 /* Decimal */,
|
|
120617
|
+
3 /* String */,
|
|
120618
|
+
7 /* Class */,
|
|
120619
|
+
6 /* List */,
|
|
120620
|
+
5 /* Dictionary */
|
|
120621
|
+
]);
|
|
120501
120622
|
LEADING_AUTHORED_ROW_ID = /^@id\(\s*"((?:[^"\\]|\\.)*)"\s*\)/;
|
|
120502
120623
|
CANONICAL_CONSTRUCTOR_INLINE_WIDTH = 88;
|
|
120503
120624
|
}
|
|
@@ -131456,7 +131577,7 @@ var init_registry2 = __esm({
|
|
|
131456
131577
|
"schema-contract/registry.mjs"() {
|
|
131457
131578
|
"use strict";
|
|
131458
131579
|
PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
131459
|
-
cliVersion: "0.48.
|
|
131580
|
+
cliVersion: "0.48.3",
|
|
131460
131581
|
projectFileUploadBatchSize: 32,
|
|
131461
131582
|
documentRecords: {
|
|
131462
131583
|
member: {
|
|
@@ -138506,7 +138627,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
|
|
|
138506
138627
|
async function main() {
|
|
138507
138628
|
const args = parseArgs(process.argv.slice(2));
|
|
138508
138629
|
if (args.command === "--version") {
|
|
138509
|
-
console.log("0.48.
|
|
138630
|
+
console.log("0.48.3");
|
|
138510
138631
|
return;
|
|
138511
138632
|
}
|
|
138512
138633
|
if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
|
package/package.json
CHANGED
|
@@ -88,7 +88,7 @@ wrappers.
|
|
|
88
88
|
The marker near the top of `SKILL.md` must exactly match the package version:
|
|
89
89
|
|
|
90
90
|
```html
|
|
91
|
-
<!-- reviewed-through-cli: 0.48.
|
|
91
|
+
<!-- reviewed-through-cli: 0.48.3 -->
|
|
92
92
|
```
|
|
93
93
|
|
|
94
94
|
The quoted version above is checked too, so this instruction cannot go stale
|
|
@@ -121,12 +121,14 @@ membership rules as member defaults.
|
|
|
121
121
|
|
|
122
122
|
## Defaults and localization
|
|
123
123
|
|
|
124
|
-
A class member
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
124
|
+
A class member whose default constructs its declared type emits a contextual
|
|
125
|
+
`= new()`, including populated defaults and defaults whose value row is
|
|
126
|
+
virtual. A default that constructs a subclass keeps the concrete type, such as
|
|
127
|
+
`Base Value = new Derived();`. Edit the declaration to change the shared
|
|
128
|
+
default, or assign the member inside an instance initializer to override only
|
|
129
|
+
that instance. Leaving the emitted construction unchanged creates no redundant
|
|
130
|
+
value rows. A nullable member with no default remains bare; an explicit null
|
|
131
|
+
default emits `= null`.
|
|
130
132
|
|
|
131
133
|
Omitted members are virtual projections of the instance's recorded constructor
|
|
132
134
|
or variant. Later edits to that source update every omitted member. Writing a
|
|
@@ -134,6 +136,12 @@ member creates a sparse override with its deterministic projected ID; removing
|
|
|
134
136
|
that member from an existing initializer resets the override and resumes source
|
|
135
137
|
tracking. Require either transition to appear in `neo diff`.
|
|
136
138
|
|
|
139
|
+
A concrete generic argument can carry a default that its type spelling does
|
|
140
|
+
not show. Pull writes nonlocalized scalar and empty aggregate binding defaults at implicit
|
|
141
|
+
construction sites, for example `DefaultData = new()`. Keeping that expression
|
|
142
|
+
unchanged or omitting it retains the virtual default; editing it creates an
|
|
143
|
+
override. A default that selects a subtype keeps the explicit subtype name.
|
|
144
|
+
|
|
137
145
|
Editing an initializer updates sparse override rows in place: projected member
|
|
138
146
|
IDs remain stable, and omitted virtual rows are never emitted as authored seed
|
|
139
147
|
records. Spelling a declared default verbatim in a new initializer lowers to
|