@neocompose/cli 0.31.3 → 0.31.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,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.31.4] - 2026-08-14
4
+
5
+ ### Fixed
6
+
7
+ - Preserve generic class constraints while compiling project-source bodies, so
8
+ an open generic member such as `TStackData extends InventoryStackData` can
9
+ be assigned to its declared base type in an `init` block.
10
+
3
11
  ## [0.31.3] - 2026-08-14
4
12
 
5
13
  ### Added
package/dist/neo.mjs CHANGED
@@ -14815,7 +14815,7 @@ function applyDelimiterToken(stack, token, lambdaBraceOffsets) {
14815
14815
  if (token.text === "{" && lambdaBraceOffsets.has(token.start)) {
14816
14816
  for (let index = stack.length - 1; index >= 0; index--) {
14817
14817
  const candidate = stack[index];
14818
- if (candidate?.text === "(" && candidate.contributes) {
14818
+ if (candidate?.text === "(" && candidate.contributes && candidate.openingLine === token.range.start.line) {
14819
14819
  restores = candidate;
14820
14820
  break;
14821
14821
  }
@@ -14824,6 +14824,7 @@ function applyDelimiterToken(stack, token, lambdaBraceOffsets) {
14824
14824
  }
14825
14825
  stack.push({
14826
14826
  text: token.text,
14827
+ openingLine: token.range.start.line,
14827
14828
  contributes: true,
14828
14829
  ...restores ? { restores } : {}
14829
14830
  });
@@ -14847,6 +14848,7 @@ function delimiterDepth(stack) {
14847
14848
  function cloneDelimiterStack(stack) {
14848
14849
  const clones = stack.map((frame) => ({
14849
14850
  text: frame.text,
14851
+ openingLine: frame.openingLine,
14850
14852
  contributes: frame.contributes
14851
14853
  }));
14852
14854
  for (let index = 0; index < stack.length; index++) {
@@ -23605,7 +23607,11 @@ function compileProjectSourceBodies(documents) {
23605
23607
  if (declaration.kind !== "class") continue;
23606
23608
  const owner = graph.declarationsByName.get(declaration.name);
23607
23609
  if (!owner) continue;
23608
- const declaringType = declarationTypeRef(owner, declaration);
23610
+ const declaringType = declarationTypeRef(
23611
+ owner,
23612
+ declaration,
23613
+ graph.typeIdsByName
23614
+ );
23609
23615
  diagnostics.push(
23610
23616
  ...declaredConstructorOverloadDiagnostics(
23611
23617
  uri,
@@ -23921,16 +23927,22 @@ function buildProjectGraph(documents) {
23921
23927
  const target = declarationsByName.get(base.name);
23922
23928
  return target?.declaration.kind === "interface" ? [target.id] : [];
23923
23929
  }) : [];
23924
- const typeParameters = classDeclaration ? classDeclaration.genericParameters.map((parameter4) => ({
23925
- id: sourceIdentity(
23926
- parameter4.annotations,
23927
- `generic:${info.id}:${parameter4.name}`
23928
- ),
23929
- name: parameter4.name,
23930
- type: { kind: "primitive", name: "unknown" },
23931
- location: location(info.uri, parameter4.range),
23932
- selectionLocation: location(info.uri, parameter4.nameRange)
23933
- })) : [];
23930
+ const typeParameters = classDeclaration ? classDeclaration.genericParameters.map((parameter4) => {
23931
+ const type = sourceTypeParameterRef(
23932
+ parameter4,
23933
+ info,
23934
+ typeIds,
23935
+ /* @__PURE__ */ new Set(),
23936
+ false
23937
+ );
23938
+ return {
23939
+ id: type.id,
23940
+ name: parameter4.name,
23941
+ type,
23942
+ location: location(info.uri, parameter4.range),
23943
+ selectionLocation: location(info.uri, parameter4.nameRange)
23944
+ };
23945
+ }) : [];
23934
23946
  return {
23935
23947
  id: info.id,
23936
23948
  name: info.declaration.name,
@@ -24268,50 +24280,49 @@ function projectRootType(documents, declarations) {
24268
24280
  }
24269
24281
  return { id: "builtin:Root", name: "Root", kind: "synthetic", members };
24270
24282
  }
24271
- function sourceTypeRef(type, owner, typeIds) {
24283
+ function sourceTypeRef(type, owner, typeIds, resolvingTypeParameters = /* @__PURE__ */ new Set()) {
24272
24284
  const nullable = type.nullable || void 0;
24285
+ const resolveNested = (nested) => sourceTypeRef(nested, owner, typeIds, resolvingTypeParameters);
24273
24286
  if (type.name === "List") {
24274
24287
  return {
24275
24288
  kind: "list",
24276
- elementType: type.typeArguments[0] ? sourceTypeRef(type.typeArguments[0], owner, typeIds) : { kind: "primitive", name: "unknown" },
24289
+ elementType: type.typeArguments[0] ? resolveNested(type.typeArguments[0]) : { kind: "primitive", name: "unknown" },
24277
24290
  ...nullable ? { nullable } : {}
24278
24291
  };
24279
24292
  }
24280
24293
  if (type.name === "Set") {
24281
24294
  return {
24282
24295
  kind: "set",
24283
- elementType: type.typeArguments[0] ? sourceTypeRef(type.typeArguments[0], owner, typeIds) : { kind: "primitive", name: "unknown" },
24296
+ elementType: type.typeArguments[0] ? resolveNested(type.typeArguments[0]) : { kind: "primitive", name: "unknown" },
24284
24297
  ...nullable ? { nullable } : {}
24285
24298
  };
24286
24299
  }
24287
24300
  if (type.name === "Dictionary") {
24288
24301
  return {
24289
24302
  kind: "dictionary",
24290
- keyType: type.typeArguments[0] ? sourceTypeRef(type.typeArguments[0], owner, typeIds) : { kind: "primitive", name: "unknown" },
24291
- valueType: type.typeArguments[1] ? sourceTypeRef(type.typeArguments[1], owner, typeIds) : { kind: "primitive", name: "unknown" },
24303
+ keyType: type.typeArguments[0] ? resolveNested(type.typeArguments[0]) : { kind: "primitive", name: "unknown" },
24304
+ valueType: type.typeArguments[1] ? resolveNested(type.typeArguments[1]) : { kind: "primitive", name: "unknown" },
24292
24305
  ...nullable ? { nullable } : {}
24293
24306
  };
24294
24307
  }
24295
24308
  if (type.name === "NeoDelegate") {
24296
- const returnType = type.typeArguments[0] ? sourceTypeRef(type.typeArguments[0], owner, typeIds) : { kind: "primitive", name: "unknown" };
24309
+ const returnType = type.typeArguments[0] ? resolveNested(type.typeArguments[0]) : { kind: "primitive", name: "unknown" };
24297
24310
  return {
24298
24311
  kind: "delegate",
24299
24312
  returnType,
24300
- parameterTypes: type.typeArguments.slice(1).map((argument2) => sourceTypeRef(argument2, owner, typeIds)),
24313
+ parameterTypes: type.typeArguments.slice(1).map(resolveNested),
24301
24314
  ...nullable ? { nullable } : {}
24302
24315
  };
24303
24316
  }
24304
24317
  if (type.name === "NeoAction") {
24305
24318
  return {
24306
24319
  kind: "action",
24307
- parameterTypes: type.typeArguments.map(
24308
- (argument2) => sourceTypeRef(argument2, owner, typeIds)
24309
- )
24320
+ parameterTypes: type.typeArguments.map(resolveNested)
24310
24321
  };
24311
24322
  }
24312
24323
  if (type.name === "Reference" && type.typeArguments[0]) {
24313
24324
  return {
24314
- ...sourceTypeRef(type.typeArguments[0], owner, typeIds),
24325
+ ...resolveNested(type.typeArguments[0]),
24315
24326
  ...nullable ? { nullable } : {}
24316
24327
  };
24317
24328
  }
@@ -24320,16 +24331,13 @@ function sourceTypeRef(type, owner, typeIds) {
24320
24331
  (candidate) => candidate.name === type.name
24321
24332
  );
24322
24333
  if (parameter4) {
24323
- return {
24324
- kind: "typeParameter",
24325
- id: sourceIdentity(
24326
- parameter4.annotations,
24327
- `generic:${owner.id}:${parameter4.name}`
24328
- ),
24329
- name: parameter4.name,
24330
- ownerClassId: owner.id,
24331
- ...nullable ? { nullable } : {}
24332
- };
24334
+ return sourceTypeParameterRef(
24335
+ parameter4,
24336
+ owner,
24337
+ typeIds,
24338
+ resolvingTypeParameters,
24339
+ nullable === true
24340
+ );
24333
24341
  }
24334
24342
  }
24335
24343
  const primitive3 = primitiveTypeName(type.name);
@@ -24345,27 +24353,37 @@ function sourceTypeRef(type, owner, typeIds) {
24345
24353
  kind: "named",
24346
24354
  typeId: targetId ?? `builtin:${type.name}`,
24347
24355
  ...type.typeArguments.length ? {
24348
- typeArguments: type.typeArguments.map(
24349
- (argument2) => sourceTypeRef(argument2, owner, typeIds)
24350
- )
24356
+ typeArguments: type.typeArguments.map(resolveNested)
24351
24357
  } : {},
24352
24358
  ...nullable ? { nullable } : {}
24353
24359
  };
24354
24360
  }
24355
- function declarationTypeRef(info, declaration) {
24361
+ function sourceTypeParameterRef(parameter4, owner, typeIds, resolvingTypeParameters, nullable) {
24362
+ const id2 = sourceIdentity(
24363
+ parameter4.annotations,
24364
+ `generic:${owner.id}:${parameter4.name}`
24365
+ );
24366
+ const next = new Set(resolvingTypeParameters);
24367
+ next.add(id2);
24368
+ const constraintSource = parameter4.constraint;
24369
+ const constraint = constraintSource !== void 0 && !resolvingTypeParameters.has(id2) ? sourceTypeRef(constraintSource, owner, typeIds, next) : void 0;
24370
+ return {
24371
+ kind: "typeParameter",
24372
+ id: id2,
24373
+ name: parameter4.name,
24374
+ ownerClassId: owner.id,
24375
+ ...constraint === void 0 ? {} : { constraint },
24376
+ ...nullable ? { nullable: true } : {}
24377
+ };
24378
+ }
24379
+ function declarationTypeRef(info, declaration, typeIds) {
24356
24380
  return {
24357
24381
  kind: "named",
24358
24382
  typeId: info.id,
24359
24383
  ...declaration.genericParameters.length ? {
24360
- typeArguments: declaration.genericParameters.map((parameter4) => ({
24361
- kind: "typeParameter",
24362
- id: sourceIdentity(
24363
- parameter4.annotations,
24364
- `generic:${info.id}:${parameter4.name}`
24365
- ),
24366
- name: parameter4.name,
24367
- ownerClassId: info.id
24368
- }))
24384
+ typeArguments: declaration.genericParameters.map(
24385
+ (parameter4) => sourceTypeParameterRef(parameter4, info, typeIds, /* @__PURE__ */ new Set(), false)
24386
+ )
24369
24387
  } : {}
24370
24388
  };
24371
24389
  }
@@ -110633,7 +110651,7 @@ var init_registry2 = __esm({
110633
110651
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
110634
110652
  formatVersion: 3,
110635
110653
  contractVersion: "3.12",
110636
- cliVersion: "0.31.3",
110654
+ cliVersion: "0.31.4",
110637
110655
  projectFileUploadBatchSize: 32,
110638
110656
  documentRecords: {
110639
110657
  member: {
@@ -117228,7 +117246,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
117228
117246
  async function main() {
117229
117247
  const args = parseArgs(process.argv.slice(2));
117230
117248
  if (args.command === "--version") {
117231
- console.log("0.31.3");
117249
+ console.log("0.31.4");
117232
117250
  return;
117233
117251
  }
117234
117252
  if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neocompose/cli",
3
- "version": "0.31.3",
3
+ "version": "0.31.4",
4
4
  "description": "Neo Compose native project-source CLI with bidirectional sync.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -9,7 +9,7 @@ description: >-
9
9
  `@neocompose/cli` or `node cli/bin/neo.mjs` in the neo-compose repository.
10
10
  ---
11
11
 
12
- <!-- reviewed-through-cli: 0.31.3 -->
12
+ <!-- reviewed-through-cli: 0.31.4 -->
13
13
 
14
14
  # Neo Compose CLI
15
15
 
@@ -83,7 +83,7 @@ wrappers.
83
83
  The marker near the top of `SKILL.md` must exactly match the package version:
84
84
 
85
85
  ```html
86
- <!-- reviewed-through-cli: 0.31.3 -->
86
+ <!-- reviewed-through-cli: 0.31.4 -->
87
87
  ```
88
88
 
89
89
  The quoted version above is checked too, so this instruction cannot go stale