@neocompose/cli 0.24.8 → 0.24.9
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,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.24.9] - 2026-08-08
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Build `neo test` execution documents from the server-prepared candidate and
|
|
8
|
+
compile every remaining authored initializer into evaluator-only IR. Tests
|
|
9
|
+
can now construct classes whose pending idless list rows capture lexical
|
|
10
|
+
selectors without requiring an earlier push.
|
|
11
|
+
- Index constructor-initializer ownership by class and member instead of
|
|
12
|
+
repeatedly scanning the project document. This reduces Neowyn's
|
|
13
|
+
initializer-owner walk from 87.8 ms to 24.9 ms median.
|
|
14
|
+
|
|
3
15
|
## [0.24.8] - 2026-08-08
|
|
4
16
|
|
|
5
17
|
### Fixed
|
package/dist/neo.mjs
CHANGED
|
@@ -54910,6 +54910,14 @@ function resolveOwnerMembersForValues(document, targetValueIds, additionalRoots,
|
|
|
54910
54910
|
const resolved = /* @__PURE__ */ new Map();
|
|
54911
54911
|
if (targetValueIds.size === 0) return resolved;
|
|
54912
54912
|
const valuesById = new Map(document.values.map((value) => [value.id, value]));
|
|
54913
|
+
const membersById = new Map(
|
|
54914
|
+
document.members.map((member) => [member.id, member])
|
|
54915
|
+
);
|
|
54916
|
+
const classesById = new Map(
|
|
54917
|
+
document.classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
|
|
54918
|
+
);
|
|
54919
|
+
const storedSchemaByClassId = /* @__PURE__ */ new Map();
|
|
54920
|
+
const defaultInstanceEnvByClassId = /* @__PURE__ */ new Map();
|
|
54913
54921
|
const rowsByContainerId = /* @__PURE__ */ new Map();
|
|
54914
54922
|
for (const value of document.values) {
|
|
54915
54923
|
if (typeof value.containerId !== "string") continue;
|
|
@@ -54933,7 +54941,25 @@ function resolveOwnerMembersForValues(document, targetValueIds, additionalRoots,
|
|
|
54933
54941
|
if (typeof memberId !== "string") return /* @__PURE__ */ new Map();
|
|
54934
54942
|
const classId = declaringClassIdByMemberId.get(memberId);
|
|
54935
54943
|
if (classId === void 0) return /* @__PURE__ */ new Map();
|
|
54936
|
-
return
|
|
54944
|
+
return defaultInstanceEnv(classId);
|
|
54945
|
+
}
|
|
54946
|
+
function defaultInstanceEnv(classId) {
|
|
54947
|
+
const cached = defaultInstanceEnvByClassId.get(classId);
|
|
54948
|
+
if (cached !== void 0) return cached;
|
|
54949
|
+
const created = resolveInstanceEnv(classId, void 0, document.classes);
|
|
54950
|
+
defaultInstanceEnvByClassId.set(classId, created);
|
|
54951
|
+
return created;
|
|
54952
|
+
}
|
|
54953
|
+
function storedSchema(classId) {
|
|
54954
|
+
const cached = storedSchemaByClassId.get(classId);
|
|
54955
|
+
if (cached !== void 0) return cached;
|
|
54956
|
+
const created = mergeStoredInstanceSchema(
|
|
54957
|
+
classId,
|
|
54958
|
+
document.classes,
|
|
54959
|
+
document.members
|
|
54960
|
+
);
|
|
54961
|
+
storedSchemaByClassId.set(classId, created);
|
|
54962
|
+
return created;
|
|
54937
54963
|
}
|
|
54938
54964
|
function searchRow(member, valueId, rootOwner, env, rootKind) {
|
|
54939
54965
|
if (targetValueIds.has(valueId) && !resolved.has(valueId)) {
|
|
@@ -54972,16 +54998,10 @@ function resolveOwnerMembersForValues(document, targetValueIds, additionalRoots,
|
|
|
54972
54998
|
if (isMemberClassBase(member)) {
|
|
54973
54999
|
if (!isRecordValue(body.value)) return;
|
|
54974
55000
|
const effectiveClassId = body.classId ?? member.classId;
|
|
54975
|
-
const schemaClass2 =
|
|
54976
|
-
(candidate) => candidate.id === effectiveClassId
|
|
54977
|
-
);
|
|
55001
|
+
const schemaClass2 = classesById.get(effectiveClassId);
|
|
54978
55002
|
if (schemaClass2 === void 0) return;
|
|
54979
|
-
const merged =
|
|
54980
|
-
|
|
54981
|
-
document.classes,
|
|
54982
|
-
document.members
|
|
54983
|
-
);
|
|
54984
|
-
const env = resolveInstanceEnv(
|
|
55003
|
+
const merged = storedSchema(effectiveClassId);
|
|
55004
|
+
const env = member.classArguments === void 0 || member.classArguments === null ? defaultInstanceEnv(effectiveClassId) : resolveInstanceEnv(
|
|
54985
55005
|
effectiveClassId,
|
|
54986
55006
|
member.classArguments,
|
|
54987
55007
|
document.classes
|
|
@@ -54990,9 +55010,7 @@ function resolveOwnerMembersForValues(document, targetValueIds, additionalRoots,
|
|
|
54990
55010
|
if (entry.memberId === null) continue;
|
|
54991
55011
|
const childValueId = body.value[entry.schemaKey];
|
|
54992
55012
|
if (childValueId === void 0) continue;
|
|
54993
|
-
const childMember =
|
|
54994
|
-
(candidate) => candidate.id === entry.memberId
|
|
54995
|
-
);
|
|
55013
|
+
const childMember = membersById.get(entry.memberId);
|
|
54996
55014
|
if (childMember === void 0) continue;
|
|
54997
55015
|
const substituted = trySubstituteMember(childMember, env);
|
|
54998
55016
|
if (substituted === null) continue;
|
|
@@ -55002,9 +55020,7 @@ function resolveOwnerMembersForValues(document, targetValueIds, additionalRoots,
|
|
|
55002
55020
|
}
|
|
55003
55021
|
if (isMemberDictionaryBase(member)) {
|
|
55004
55022
|
if (!isRecordValue(body.value)) return;
|
|
55005
|
-
const entryMemberRecord =
|
|
55006
|
-
(candidate) => candidate.id === member.entryMemberId
|
|
55007
|
-
);
|
|
55023
|
+
const entryMemberRecord = membersById.get(member.entryMemberId);
|
|
55008
55024
|
if (entryMemberRecord === void 0) return;
|
|
55009
55025
|
const entryEnv = overlayStamp(ambientEnv, body.genericBindings);
|
|
55010
55026
|
const entryMember = trySubstituteMember(entryMemberRecord, entryEnv);
|
|
@@ -55015,9 +55031,7 @@ function resolveOwnerMembersForValues(document, targetValueIds, additionalRoots,
|
|
|
55015
55031
|
return;
|
|
55016
55032
|
}
|
|
55017
55033
|
if (isMemberListBase(member)) {
|
|
55018
|
-
const entryMemberRecord =
|
|
55019
|
-
(candidate) => candidate.id === member.entryMemberId
|
|
55020
|
-
);
|
|
55034
|
+
const entryMemberRecord = membersById.get(member.entryMemberId);
|
|
55021
55035
|
if (entryMemberRecord === void 0) return;
|
|
55022
55036
|
const entryEnv = overlayStamp(ambientEnv, body.genericBindings);
|
|
55023
55037
|
const entryMember = trySubstituteMember(entryMemberRecord, entryEnv);
|
|
@@ -63462,21 +63476,17 @@ function initializerEvaluatorLookups(document) {
|
|
|
63462
63476
|
});
|
|
63463
63477
|
return lookups;
|
|
63464
63478
|
}
|
|
63465
|
-
function buildInitializerRootValue(document) {
|
|
63479
|
+
function buildInitializerRootValue(document, lookups) {
|
|
63466
63480
|
const rootValue = {};
|
|
63467
|
-
const memberById = new Map(
|
|
63468
|
-
document.members.map((member) => [member.id, member])
|
|
63469
|
-
);
|
|
63470
|
-
const valueById = new Map(document.values.map((row) => [row.id, row]));
|
|
63471
63481
|
for (const { root, memberId } of projectRootMembersInDisplayOrder(
|
|
63472
63482
|
document.project
|
|
63473
63483
|
)) {
|
|
63474
|
-
const member = memberById
|
|
63475
|
-
if (member ===
|
|
63484
|
+
const member = lookups.memberById(memberId);
|
|
63485
|
+
if (member === null || typeof member.valueId !== "string") {
|
|
63476
63486
|
rootValue[root.key] = null;
|
|
63477
63487
|
continue;
|
|
63478
63488
|
}
|
|
63479
|
-
rootValue[root.key] = valueById
|
|
63489
|
+
rootValue[root.key] = lookups.valueById(member.valueId)?.value ?? null;
|
|
63480
63490
|
}
|
|
63481
63491
|
return rootValue;
|
|
63482
63492
|
}
|
|
@@ -63489,6 +63499,7 @@ function evaluateMemberInitializer(args) {
|
|
|
63489
63499
|
args.init
|
|
63490
63500
|
);
|
|
63491
63501
|
}
|
|
63502
|
+
const databaseVM = initializerEvaluatorLookups(args.document);
|
|
63492
63503
|
const ctx = {
|
|
63493
63504
|
vm: {
|
|
63494
63505
|
project: args.document.project,
|
|
@@ -63502,10 +63513,10 @@ function evaluateMemberInitializer(args) {
|
|
|
63502
63513
|
interfaces: args.document.interfaces,
|
|
63503
63514
|
localizedTexts: args.document.localizedTexts,
|
|
63504
63515
|
localizationConfig: args.document.localizationConfig,
|
|
63505
|
-
databaseVM
|
|
63516
|
+
databaseVM
|
|
63506
63517
|
},
|
|
63507
63518
|
thisValue: null,
|
|
63508
|
-
rootValue: buildInitializerRootValue(args.document),
|
|
63519
|
+
rootValue: buildInitializerRootValue(args.document, databaseVM),
|
|
63509
63520
|
saveStaticBindings: args.saveStaticBindings,
|
|
63510
63521
|
sessionStaticBindings: args.sessionStaticBindings,
|
|
63511
63522
|
...args.storedConstructionReplay === true ? {
|
|
@@ -84137,6 +84148,7 @@ function assertServerPreparationSucceeds(args) {
|
|
|
84137
84148
|
prepared
|
|
84138
84149
|
);
|
|
84139
84150
|
}
|
|
84151
|
+
return prepared;
|
|
84140
84152
|
} catch (error) {
|
|
84141
84153
|
throw locateBodyCompileFailure(error, args.sourceByRecord);
|
|
84142
84154
|
}
|
|
@@ -84354,7 +84366,7 @@ function replayStoredConstructionV4(args) {
|
|
|
84354
84366
|
"Construction replay cannot compile document bodies without a compiler project."
|
|
84355
84367
|
);
|
|
84356
84368
|
}
|
|
84357
|
-
|
|
84369
|
+
compilePulledProjectDocumentForEvaluationV4(document, compilationProject);
|
|
84358
84370
|
}
|
|
84359
84371
|
const root = document.values.find((value) => value.id === args.valueId);
|
|
84360
84372
|
if (root === void 0) {
|
|
@@ -84550,7 +84562,16 @@ function compilePulledValueInitializerBodyV4(document, valueId, compilationProje
|
|
|
84550
84562
|
...compilationProject === void 0 ? {} : { compilationProject }
|
|
84551
84563
|
});
|
|
84552
84564
|
}
|
|
84553
|
-
function
|
|
84565
|
+
function compilePulledProjectDocumentForEvaluationV4(document, compilationProject) {
|
|
84566
|
+
const sharedCompilationProject = compilationProject ?? createNeoScriptCompilationProject({
|
|
84567
|
+
project: document.project,
|
|
84568
|
+
projectFiles: document.projectFiles,
|
|
84569
|
+
members: document.members,
|
|
84570
|
+
classes: document.classes,
|
|
84571
|
+
enums: document.enums,
|
|
84572
|
+
interfaces: document.interfaces,
|
|
84573
|
+
constructors: document.constructors ?? []
|
|
84574
|
+
});
|
|
84554
84575
|
const compileArgs = {
|
|
84555
84576
|
project: document.project,
|
|
84556
84577
|
projectFiles: document.projectFiles,
|
|
@@ -84559,7 +84580,7 @@ function compilePulledProjectDocumentBodiesV4(document, compilationProject) {
|
|
|
84559
84580
|
enums: document.enums,
|
|
84560
84581
|
interfaces: document.interfaces,
|
|
84561
84582
|
constructors: document.constructors ?? [],
|
|
84562
|
-
compilationProject
|
|
84583
|
+
compilationProject: sharedCompilationProject
|
|
84563
84584
|
};
|
|
84564
84585
|
for (const constructor2 of compileArgs.constructors) {
|
|
84565
84586
|
compileConstructorRecord({ ...compileArgs, constructor: constructor2 });
|
|
@@ -84579,6 +84600,20 @@ function compilePulledProjectDocumentBodiesV4(document, compilationProject) {
|
|
|
84579
84600
|
thisClass: ownerClassByMemberId.get(member.id) ?? null
|
|
84580
84601
|
});
|
|
84581
84602
|
}
|
|
84603
|
+
for (const site of valueInitializerCompilationSites(document).values()) {
|
|
84604
|
+
if (isInitValueContent(site.row) && site.row.init.compiled !== void 0) {
|
|
84605
|
+
continue;
|
|
84606
|
+
}
|
|
84607
|
+
compileValueRowInitializerBody({
|
|
84608
|
+
...compileArgs,
|
|
84609
|
+
member: site.member,
|
|
84610
|
+
valueRow: site.row,
|
|
84611
|
+
valueId: String(Reflect.get(site.row, "id")),
|
|
84612
|
+
initializerOwnerClass: site.ownerClass,
|
|
84613
|
+
lexicalThisClass: site.lexicalThisClass,
|
|
84614
|
+
storedConstructionReplay: true
|
|
84615
|
+
});
|
|
84616
|
+
}
|
|
84582
84617
|
}
|
|
84583
84618
|
function assertPulledConstructorsCompiled(document) {
|
|
84584
84619
|
const uncompiled = (document.constructors ?? []).find(
|
|
@@ -100098,6 +100133,7 @@ async function prepareLocalPushArtifactsV4(workspace, status, onPhase = () => vo
|
|
|
100098
100133
|
status.changes,
|
|
100099
100134
|
localizedTextCreateEnvelopeConfig2(workspace, status.changes)
|
|
100100
100135
|
);
|
|
100136
|
+
let preparedChanges = null;
|
|
100101
100137
|
if (options.fullValidation) {
|
|
100102
100138
|
onPhase("Verifying the complete source round trip\u2026");
|
|
100103
100139
|
verifyProjectSourceCommitAgainstStateV4({
|
|
@@ -100114,7 +100150,7 @@ async function prepareLocalPushArtifactsV4(workspace, status, onPhase = () => vo
|
|
|
100114
100150
|
onPhase(
|
|
100115
100151
|
`Rehearsing server validation for ${transportChanges.length.toLocaleString("en-US")} change(s)\u2026`
|
|
100116
100152
|
);
|
|
100117
|
-
assertServerPreparationSucceeds({
|
|
100153
|
+
preparedChanges = assertServerPreparationSucceeds({
|
|
100118
100154
|
workspace,
|
|
100119
100155
|
changes: transportChanges,
|
|
100120
100156
|
authoredValueSeeds: transportSeeds,
|
|
@@ -100129,7 +100165,8 @@ async function prepareLocalPushArtifactsV4(workspace, status, onPhase = () => vo
|
|
|
100129
100165
|
transactionOperation,
|
|
100130
100166
|
transportChanges,
|
|
100131
100167
|
transportSeeds,
|
|
100132
|
-
preparedFiles
|
|
100168
|
+
preparedFiles,
|
|
100169
|
+
preparedChanges
|
|
100133
100170
|
};
|
|
100134
100171
|
}
|
|
100135
100172
|
async function prepareLocalCandidateV4(workspace, options = {}) {
|
|
@@ -100203,8 +100240,23 @@ async function prepareLocalCandidateV4(workspace, options = {}) {
|
|
|
100203
100240
|
if (typeof baseId === "string") {
|
|
100204
100241
|
records2.delete(`${change.recordKind}:${baseId}`);
|
|
100205
100242
|
}
|
|
100243
|
+
}
|
|
100244
|
+
const candidateChanges = preparedLocal?.preparedChanges ?? documentStatus.changes.map((change) => ({
|
|
100245
|
+
recordKind: change.recordKind,
|
|
100246
|
+
recordId: change.recordId,
|
|
100247
|
+
operation: change.kind,
|
|
100248
|
+
nextData: change.nextData
|
|
100249
|
+
}));
|
|
100250
|
+
for (const change of candidateChanges) {
|
|
100206
100251
|
records2.delete(`${change.recordKind}:${change.recordId}`);
|
|
100207
|
-
if (change.nextData === void 0)
|
|
100252
|
+
if (change.operation === "delete" || change.nextData === void 0) {
|
|
100253
|
+
continue;
|
|
100254
|
+
}
|
|
100255
|
+
if (!isObjectRecord2(change.nextData)) {
|
|
100256
|
+
throw new Error(
|
|
100257
|
+
`Prepared ${change.recordKind} record ${JSON.stringify(change.recordId)} has invalid data.`
|
|
100258
|
+
);
|
|
100259
|
+
}
|
|
100208
100260
|
const nextId = typeof change.nextData.id === "string" ? change.nextData.id : change.recordId;
|
|
100209
100261
|
records2.set(`${change.recordKind}:${nextId}`, {
|
|
100210
100262
|
recordKind: change.recordKind,
|
|
@@ -100214,9 +100266,11 @@ async function prepareLocalCandidateV4(workspace, options = {}) {
|
|
|
100214
100266
|
data: change.nextData
|
|
100215
100267
|
});
|
|
100216
100268
|
}
|
|
100269
|
+
const document = readPulledProjectDocumentV4(records2);
|
|
100270
|
+
compilePulledProjectDocumentForEvaluationV4(document);
|
|
100217
100271
|
return {
|
|
100218
100272
|
status,
|
|
100219
|
-
document
|
|
100273
|
+
document,
|
|
100220
100274
|
sourceHash,
|
|
100221
100275
|
preparedLocal
|
|
100222
100276
|
};
|
|
@@ -101670,7 +101724,7 @@ var init_registry2 = __esm({
|
|
|
101670
101724
|
PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
101671
101725
|
formatVersion: 3,
|
|
101672
101726
|
contractVersion: "3.9",
|
|
101673
|
-
cliVersion: "0.24.
|
|
101727
|
+
cliVersion: "0.24.9",
|
|
101674
101728
|
projectFileUploadBatchSize: 32,
|
|
101675
101729
|
documentRecords: {
|
|
101676
101730
|
member: {
|
package/package.json
CHANGED
|
@@ -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.24.
|
|
12
|
+
<!-- reviewed-through-cli: 0.24.9 -->
|
|
13
13
|
|
|
14
14
|
# Neo Compose CLI
|
|
15
15
|
|
|
@@ -30,6 +30,9 @@ Those are not part of format 4.
|
|
|
30
30
|
existed before the task began.
|
|
31
31
|
4. Run `neo test` after NeoScript changes and `neo dialogue dryrun <ref>` after
|
|
32
32
|
dialogue changes.
|
|
33
|
+
`neo test` compiles the complete pending candidate, including idless nested
|
|
34
|
+
construction rows, so tests must work before the first push; do not add IDs
|
|
35
|
+
or push merely to obtain compiled initializer bodies.
|
|
33
36
|
5. Run `neo push --dry-run` before every real push. It performs the full local
|
|
34
37
|
source emission, ID-assignment, transport-shape, hash, and repeat-verification path,
|
|
35
38
|
then rehearses the server's preparation phase — schema-commit
|
|
@@ -82,7 +82,7 @@ wrappers.
|
|
|
82
82
|
The marker near the top of `SKILL.md` must exactly match the package version:
|
|
83
83
|
|
|
84
84
|
```html
|
|
85
|
-
<!-- reviewed-through-cli: 0.24.
|
|
85
|
+
<!-- reviewed-through-cli: 0.24.9 -->
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
The quoted version above is checked too, so this instruction cannot go stale
|