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.
|
|
1581
|
-
lines.push("
|
|
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 (
|
|
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 "
|
|
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";
|