nexarch 0.9.12 → 0.9.14

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.
@@ -898,14 +898,17 @@ function scanProject(dir) {
898
898
  };
899
899
  }
900
900
  // ─── Relationship type selection ──────────────────────────────────────────────
901
- function pickRelationshipType(toEntityTypeCode, _fromEntityTypeCode = "application") {
901
+ function pickRelationshipType(toEntityTypeCode, toEntitySubtypeCode, _fromEntityTypeCode = "application") {
902
902
  switch (toEntityTypeCode) {
903
903
  case "model":
904
904
  return "uses_model";
905
905
  case "platform":
906
- case "platform_component":
907
- // runs_on is the valid ontology relationship from application/tech to platform
908
906
  return "runs_on";
907
+ case "platform_component":
908
+ // platform_service (Vercel Analytics, Vercel Postgres, Cloudinary, etc.) are opt-in
909
+ // managed services — integrates_with is the semantically correct relationship.
910
+ // Other platform_component subtypes (platform_runtime, platform_control_plane) use depends_on.
911
+ return toEntitySubtypeCode === "platform_service" ? "integrates_with" : "depends_on";
909
912
  case "skill":
910
913
  return "uses";
911
914
  case "technology_component":
@@ -1371,7 +1374,7 @@ export async function initProject(args) {
1371
1374
  if (!rootDepNames.has(r.input) && !rootDepNames.has(r.normalised))
1372
1375
  continue;
1373
1376
  const depSpec = rootDepVersions.get(r.input) ?? rootDepVersions.get(r.normalised);
1374
- addRel(pickRelationshipType(r.entityTypeCode), projectExternalKey, r.canonicalExternalRef, 0.9, {
1377
+ addRel(pickRelationshipType(r.entityTypeCode, r.entitySubtypeCode), projectExternalKey, r.canonicalExternalRef, 0.9, {
1375
1378
  source: depSpec?.source ?? "manifest_scan",
1376
1379
  detected_at: nowIso,
1377
1380
  ...buildVersionAttributes(depSpec?.versionRaw ?? null, depSpec?.source ?? "manifest_scan"),
@@ -1391,7 +1394,7 @@ export async function initProject(args) {
1391
1394
  const r = resolvedByInput.get(dep.name);
1392
1395
  if (!r?.canonicalExternalRef || !r.entityTypeCode)
1393
1396
  continue;
1394
- addRel(pickRelationshipType(r.entityTypeCode, sp.entityType), sp.externalKey, r.canonicalExternalRef, 0.9, {
1397
+ addRel(pickRelationshipType(r.entityTypeCode, r.entitySubtypeCode, sp.entityType), sp.externalKey, r.canonicalExternalRef, 0.9, {
1395
1398
  source: dep.source,
1396
1399
  detected_at: nowIso,
1397
1400
  ...buildVersionAttributes(dep.versionRaw, dep.source),
@@ -1524,7 +1527,7 @@ export async function initProject(args) {
1524
1527
  .map((d) => resolvedByInput.get(d.name))
1525
1528
  .filter((r) => !!r?.canonicalExternalRef)
1526
1529
  .map((r) => {
1527
- const relationshipTypeCode = pickRelationshipType(r.entityTypeCode, sp.entityType);
1530
+ const relationshipTypeCode = pickRelationshipType(r.entityTypeCode, r.entitySubtypeCode, sp.entityType);
1528
1531
  const relationshipKey = `${relationshipTypeCode}::${sp.externalKey}::${r.canonicalExternalRef}`;
1529
1532
  return {
1530
1533
  canonicalExternalRef: r.canonicalExternalRef,
@@ -1577,8 +1580,9 @@ export async function initProject(args) {
1577
1580
  function buildEnrichmentDirective() {
1578
1581
  const lines = [];
1579
1582
  lines.push("─── ENRICHMENT REQUIRED ─────────────────────────────────────────────────");
1580
- lines.push("init-project wrote a skeleton. You must complete enrichment NOW, inline,");
1581
- lines.push("in this same session. Do NOT report the project as registered until done.");
1583
+ lines.push("init-project wrote a skeleton. Complete enrichment NOW — do not ask the");
1584
+ lines.push("user for permission, do not summarise and pause, just execute the steps.");
1585
+ lines.push("Do NOT report the project as registered until enrichment is done.");
1582
1586
  lines.push("");
1583
1587
  lines.push(`PROJECT : ${projectExternalKey}`);
1584
1588
  lines.push(`DIR : ${dir}`);
@@ -1616,12 +1620,24 @@ export async function initProject(args) {
1616
1620
  lines.push(` … and ${unresolvedItems.length - 20} more`);
1617
1621
  }
1618
1622
  lines.push("");
1619
- lines.push("THEN_RUN (once you have read the READMEs):");
1623
+ lines.push("THEN_RUN (execute these steps immediately do not pause or ask for confirmation):");
1620
1624
  let step = 1;
1621
- lines.push(` ${step++}. nexarch update-entity --key "${projectExternalKey}" --entity-type "${entityTypeOverride}"${entityTypeOverride === "application" ? ' --subtype "app_custom_built" --icon "<lucide-icon>"' : ""} --name "..." --description "..."`);
1625
+ lines.push(` ${step++}. nexarch update-entity --key "${projectExternalKey}" --entity-type "${entityTypeOverride}"${entityTypeOverride === "application" ? ' --subtype "<subtype>" --icon "<lucide-icon>"' : ""} --name "..." --description "..."`);
1626
+ if (entityTypeOverride === "application") {
1627
+ lines.push(` Valid subtypes: app_custom_built app_saas app_mobile app_cli app_integration_service app_data_pipeline`);
1628
+ lines.push(` (choose app_custom_built as the default if none of the others clearly apply)`);
1629
+ }
1622
1630
  if (subPackages.length > 0) {
1623
1631
  lines.push(` ${step++}. Update each sub-package listed under CLASSIFY_THESE above.`);
1624
1632
  }
1633
+ if (entityTypeOverride === "application") {
1634
+ lines.push(` ${step++}. Identify functional subsystems from the README and architecture docs.`);
1635
+ lines.push(` Look for named logical areas (e.g. Billing System, Auth Subsystem, Data Layer, API Service Layer).`);
1636
+ lines.push(` Only register subsystems that are explicitly named or described — do not invent them.`);
1637
+ lines.push(` For each one found:`);
1638
+ lines.push(` nexarch update-entity --key "application_component:${projectExternalKey.split(":")[1] ?? "project"}-<subsystem-slug>" --entity-type application_component --subtype app_comp_subsystem --name "..." --description "..."`);
1639
+ lines.push(` nexarch add-relationship --from "application_component:${projectExternalKey.split(":")[1] ?? "project"}-<subsystem-slug>" --to "${projectExternalKey}" --type part_of`);
1640
+ }
1625
1641
  lines.push(` ${step++}. Scan the READMEs for platforms/SaaS not auto-detected (Vercel, Neon, Stripe, etc.).`);
1626
1642
  lines.push(` For each found: nexarch resolve-names --names "..." --json → nexarch update-entity → nexarch add-relationship`);
1627
1643
  lines.push(` ${step++}. Look for ADRs (docs/adr/, decisions/, ADR-*.md) and register decision_record entities.`);
@@ -52,7 +52,7 @@ export async function updateEntity(args) {
52
52
  console.error("error: batch entity updates were removed. Use explicit per-entity update-entity commands for enrichment quality.");
53
53
  process.exit(1);
54
54
  }
55
- const externalKey = parseOptionValue(args, "--key");
55
+ const externalKey = parseOptionValue(args, "--key") ?? parseOptionValue(args, "--external-key");
56
56
  const name = parseOptionValue(args, "--name");
57
57
  const description = parseOptionValue(args, "--description");
58
58
  const entityTypeCode = parseOptionValue(args, "--entity-type") ?? "application";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexarch",
3
- "version": "0.9.12",
3
+ "version": "0.9.14",
4
4
  "description": "Your architecture workspace for AI delivery.",
5
5
  "keywords": [
6
6
  "nexarch",