nexarch 0.9.17 → 0.9.19

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.
@@ -909,6 +909,9 @@ function pickRelationshipType(toEntityTypeCode, toEntitySubtypeCode, _fromEntity
909
909
  // managed services — integrates_with is the semantically correct relationship.
910
910
  // Other platform_component subtypes (platform_runtime, platform_control_plane) use depends_on.
911
911
  return toEntitySubtypeCode === "platform_service" ? "integrates_with" : "depends_on";
912
+ case "application":
913
+ // Application-to-application: a hard runtime dependency, not a peer integration concern.
914
+ return "depends_on";
912
915
  case "skill":
913
916
  return "uses";
914
917
  case "technology_component":
@@ -1349,10 +1352,23 @@ export async function initProject(args) {
1349
1352
  if (r.normalised && r.canonicalExternalRef)
1350
1353
  resolvedByInput.set(r.normalised, r);
1351
1354
  }
1355
+ // Build intra-monorepo lookup: normalised package name → sub-package externalKey + entityType.
1356
+ // Used to detect workspace deps between applications in the same repo (e.g. "workspace:*" refs
1357
+ // that won't resolve against the global reference library but should still be wired).
1358
+ const intraMonorepoByName = new Map();
1359
+ for (const sp of subPackages) {
1360
+ if (!sp.externalKey)
1361
+ continue;
1362
+ intraMonorepoByName.set(sp.name.toLowerCase(), { externalKey: sp.externalKey, entityType: sp.entityType });
1363
+ const norm = normalizeToken(sp.name);
1364
+ if (norm !== sp.name.toLowerCase())
1365
+ intraMonorepoByName.set(norm, { externalKey: sp.externalKey, entityType: sp.entityType });
1366
+ }
1352
1367
  // Build relationships:
1353
1368
  // - Root-level deps → wired to the top-level project entity
1354
1369
  // - Sub-package deps → wired to each sub-package entity
1355
1370
  // - Sub-packages that are apps → part_of the top-level project
1371
+ // - Sub-package deps that resolve to another sub-package → integrates_with
1356
1372
  const relationships = [];
1357
1373
  const seenRelPairs = new Set();
1358
1374
  let relationshipAddAttempts = 0;
@@ -1385,20 +1401,43 @@ export async function initProject(args) {
1385
1401
  if (!sp.externalKey || seenSubKeys.has(`rel:${sp.externalKey}`))
1386
1402
  continue;
1387
1403
  seenSubKeys.add(`rel:${sp.externalKey}`);
1388
- // Apps are part_of the top-level project
1404
+ // Wire structural relationship to the top-level project entity:
1405
+ // - application_component → part_of → root (component within a single deployable app)
1406
+ // - application → root:
1407
+ // product root: root composes sub-app (product is composed of its constituent apps)
1408
+ // application root: sub-app part_of root (treat as a bounded sub-application)
1389
1409
  if (sp.entityType === "application_component") {
1390
1410
  addRel("part_of", sp.externalKey, projectExternalKey);
1391
1411
  }
1412
+ else if (sp.entityType === "application") {
1413
+ if (entityTypeOverride === "product") {
1414
+ addRel("composes", projectExternalKey, sp.externalKey);
1415
+ }
1416
+ else {
1417
+ addRel("part_of", sp.externalKey, projectExternalKey);
1418
+ }
1419
+ }
1392
1420
  // Wire each sub-package's resolved deps to itself
1393
1421
  for (const dep of sp.depSpecs) {
1394
1422
  const r = resolvedByInput.get(dep.name);
1395
- if (!r?.canonicalExternalRef || !r.entityTypeCode)
1423
+ if (r?.canonicalExternalRef && r.entityTypeCode) {
1424
+ addRel(pickRelationshipType(r.entityTypeCode, r.entitySubtypeCode, sp.entityType), sp.externalKey, r.canonicalExternalRef, 0.9, {
1425
+ source: dep.source,
1426
+ detected_at: nowIso,
1427
+ ...buildVersionAttributes(dep.versionRaw, dep.source),
1428
+ });
1396
1429
  continue;
1397
- addRel(pickRelationshipType(r.entityTypeCode, r.entitySubtypeCode, sp.entityType), sp.externalKey, r.canonicalExternalRef, 0.9, {
1398
- source: dep.source,
1399
- detected_at: nowIso,
1400
- ...buildVersionAttributes(dep.versionRaw, dep.source),
1401
- });
1430
+ }
1431
+ // Check if the dep resolves to another sub-package in the same monorepo.
1432
+ // This catches workspace:* references and local inter-app dependencies.
1433
+ const intra = intraMonorepoByName.get(dep.name.toLowerCase())
1434
+ ?? intraMonorepoByName.get(normalizeToken(dep.name));
1435
+ if (intra && intra.externalKey !== sp.externalKey) {
1436
+ addRel("depends_on", sp.externalKey, intra.externalKey, 0.85, {
1437
+ source: dep.source,
1438
+ detected_at: nowIso,
1439
+ });
1440
+ }
1402
1441
  }
1403
1442
  }
1404
1443
  // Company org is accountable_for the top-level project entity
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexarch",
3
- "version": "0.9.17",
3
+ "version": "0.9.19",
4
4
  "description": "Your architecture workspace for AI delivery.",
5
5
  "keywords": [
6
6
  "nexarch",