nexarch 0.1.25 → 0.1.28

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.
@@ -4,7 +4,7 @@ import { join } from "path";
4
4
  import process from "process";
5
5
  import { requireCredentials } from "../lib/credentials.js";
6
6
  import { callMcpTool, mcpInitialize, mcpListTools } from "../lib/mcp.js";
7
- const CLI_VERSION = "0.1.25";
7
+ const CLI_VERSION = "0.1.28";
8
8
  const AGENT_ENTITY_TYPE = "agent";
9
9
  const TECH_COMPONENT_ENTITY_TYPE = "technology_component";
10
10
  function parseFlag(args, flag) {
@@ -282,14 +282,19 @@ function scanProject(dir) {
282
282
  return { projectName, packageJsonCount: pkgPaths.length, detectedNames: Array.from(names), rootDepNames, subPackages };
283
283
  }
284
284
  // ─── Relationship type selection ──────────────────────────────────────────────
285
- function pickRelationshipType(entityTypeCode) {
286
- switch (entityTypeCode) {
285
+ function pickRelationshipType(toEntityTypeCode, fromEntityTypeCode = "application") {
286
+ switch (toEntityTypeCode) {
287
287
  case "model":
288
288
  return "uses_model";
289
289
  case "platform":
290
290
  case "platform_component":
291
291
  case "skill":
292
292
  return "uses";
293
+ case "technology_component":
294
+ // tech→tech depends_on is not allowed by ontology; use "uses" instead
295
+ if (fromEntityTypeCode === "technology_component")
296
+ return "uses";
297
+ return "depends_on";
293
298
  default:
294
299
  return "depends_on";
295
300
  }
@@ -454,7 +459,7 @@ export async function initProject(args) {
454
459
  const r = resolvedByInput.get(depName);
455
460
  if (!r?.canonicalExternalRef || !r.entityTypeCode)
456
461
  continue;
457
- addRel(pickRelationshipType(r.entityTypeCode), sp.externalKey, r.canonicalExternalRef);
462
+ addRel(pickRelationshipType(r.entityTypeCode, sp.entityType), sp.externalKey, r.canonicalExternalRef);
458
463
  }
459
464
  }
460
465
  if (!asJson)
@@ -468,64 +473,11 @@ export async function initProject(args) {
468
473
  const relsRaw = await callMcpTool("nexarch_upsert_relationships", { relationships, agentContext, policyContext }, mcpOpts);
469
474
  relsResult = parseToolText(relsRaw);
470
475
  }
471
- const output = {
472
- ok: Number(entitiesResult.summary?.failed ?? 0) === 0,
473
- project: { name: displayName, externalKey: projectExternalKey, entityType: entityTypeOverride },
474
- entities: entitiesResult.summary ?? {},
475
- relationships: relsResult?.summary ?? { requested: 0, succeeded: 0, failed: 0 },
476
- resolved: resolvedItems.length,
477
- unresolved: unresolvedItems.length,
478
- unresolvedSample: unresolvedItems.slice(0, 10).map((r) => r.input),
479
- entityErrors: entitiesResult.errors ?? [],
480
- relationshipErrors: relsResult?.errors ?? [],
481
- };
482
- if (asJson) {
483
- process.stdout.write(`${JSON.stringify(output, null, 2)}\n`);
484
- if (!output.ok)
485
- process.exitCode = 1;
486
- return;
487
- }
488
- console.log(`\nDone.`);
489
- console.log(` Entities : ${output.entities.succeeded ?? 0} written, ${output.entities.failed ?? 0} failed`);
490
- console.log(` Relationships: ${output.relationships.succeeded ?? 0} written`);
491
- if (unresolvedItems.length > 0) {
492
- console.log(` Candidates : ${unresolvedItems.length} added to reference candidates`);
493
- }
494
- if (output.entityErrors.length > 0) {
495
- console.log("\nEntity errors:");
496
- for (const err of output.entityErrors) {
497
- console.log(` ${err.externalKey}: ${err.error} — ${err.message}`);
498
- }
499
- }
500
- // ─── Enrichment task ────────────────────────────────────────────────────────
476
+ // Build structured enrichment task (included in JSON output and printed in human mode)
501
477
  const readmeHints = ["README.md", "README.mdx", "docs/README.md", "docs/index.md"]
502
478
  .filter((f) => existsSync(join(dir, f)));
503
- console.log(`
504
- ╔══════════════════════════════════════════════════════════════════╗
505
- ║ ENRICHMENT TASK — action required ║
506
- ╚══════════════════════════════════════════════════════════════════╝
507
-
508
- The mechanical scan has written a skeleton graph entry for this project.
509
- You now need to enrich it with meaningful content.
510
-
511
- PROJECT ENTITY : ${projectExternalKey}
512
- PROJECT DIR : ${dir}
513
- ${readmeHints.length > 0 ? `README FILES : ${readmeHints.join(", ")}` : "README FILES : (none found — check docs/)"}
514
-
515
- STEP 1 — Read the project README / docs and build your understanding of:
516
- • What does this project do? (business purpose, key features)
517
- • Who are the users?
518
- • What is the high-level architecture?
519
- • Any notable technical decisions or constraints?
520
-
521
- STEP 2 — Enrich the project entity. Run this command with the description you've written:
522
-
523
- npx nexarch update-entity \\
524
- --key "${projectExternalKey}" \\
525
- --entity-type "${entityTypeOverride}"${entityTypeOverride === "application" ? ' \\\n --subtype "app_custom_built"' : ""} \\
526
- --name "<proper product name from README>" \\
527
- --description "<2–4 sentence summary of what it does and why>"
528
- ${subPackages.length > 0 ? `
479
+ function buildEnrichmentInstructions() {
480
+ const subPkgSection = subPackages.length === 0 ? "" : `
529
481
  STEP 3 — Classify and register each sub-package as its own entity.
530
482
  The scanner found ${subPackages.length} workspace package(s):
531
483
 
@@ -588,13 +540,95 @@ ${subPackages.map((sp) => ` • ${sp.name} (${sp.relativePath})`).join("\n")
588
540
 
589
541
  Pre-resolved dependencies per sub-package (wire these after registering each entity):
590
542
  ${subPackages.map((sp) => {
591
- const resolved = sp.depNames
592
- .map((d) => resolvedByInput.get(d))
593
- .filter((r) => !!r?.canonicalExternalRef);
594
- if (resolved.length === 0)
595
- return ` • ${sp.name}: (no pre-resolved deps — check package.json manually)`;
596
- const lines = resolved.map((r) => ` --to "${r.canonicalExternalRef}" # ${r.canonicalName}`);
597
- return ` • ${sp.name} (<sub-app-key> depends_on):\n${lines.join("\n")}`;
598
- }).join("\n\n")}
599
- ` : ""}`);
543
+ const resolved = sp.depNames
544
+ .map((d) => resolvedByInput.get(d))
545
+ .filter((r) => !!r?.canonicalExternalRef);
546
+ if (resolved.length === 0)
547
+ return ` • ${sp.name}: (no pre-resolved deps — check package.json manually)`;
548
+ const lines = resolved.map((r) => ` --to "${r.canonicalExternalRef}" # ${r.canonicalName}`);
549
+ return ` • ${sp.name} (<sub-app-key> depends_on):\n${lines.join("\n")}`;
550
+ }).join("\n\n")}
551
+ `;
552
+ return `
553
+ ╔══════════════════════════════════════════════════════════════════╗
554
+ ║ ENRICHMENT TASK — action required ║
555
+ ╚══════════════════════════════════════════════════════════════════╝
556
+
557
+ The mechanical scan has written a skeleton graph entry for this project.
558
+ You now need to enrich it with meaningful content.
559
+
560
+ PROJECT ENTITY : ${projectExternalKey}
561
+ PROJECT DIR : ${dir}
562
+ ${readmeHints.length > 0 ? `README FILES : ${readmeHints.join(", ")}` : "README FILES : (none found — check docs/)"}
563
+
564
+ STEP 1 — Read the project README / docs and build your understanding of:
565
+ • What does this project do? (business purpose, key features)
566
+ • Who are the users?
567
+ • What is the high-level architecture?
568
+ • Any notable technical decisions or constraints?
569
+
570
+ STEP 2 — Enrich the project entity. Run this command with the description you've written:
571
+
572
+ npx nexarch update-entity \\
573
+ --key "${projectExternalKey}" \\
574
+ --entity-type "${entityTypeOverride}"${entityTypeOverride === "application" ? " \\\n --subtype \"app_custom_built\"" : ""} \\
575
+ --name "<proper product name from README>" \\
576
+ --description "<2–4 sentence summary of what it does and why>"
577
+ ${subPkgSection}`;
578
+ }
579
+ const enrichmentTask = {
580
+ instructions: buildEnrichmentInstructions(),
581
+ projectEntity: {
582
+ externalKey: projectExternalKey,
583
+ entityType: entityTypeOverride,
584
+ readmeFiles: readmeHints,
585
+ },
586
+ subPackages: subPackages.map((sp) => {
587
+ const resolvedDeps = sp.depNames
588
+ .map((d) => resolvedByInput.get(d))
589
+ .filter((r) => !!r?.canonicalExternalRef)
590
+ .map((r) => ({ canonicalExternalRef: r.canonicalExternalRef, canonicalName: r.canonicalName, entityTypeCode: r.entityTypeCode }));
591
+ return {
592
+ name: sp.name,
593
+ relativePath: sp.relativePath,
594
+ externalKey: sp.externalKey,
595
+ inferredEntityType: sp.entityType,
596
+ inferredSubtype: sp.subtype,
597
+ resolvedDeps,
598
+ unresolvedDeps: sp.depNames.filter((d) => !resolvedByInput.has(d)),
599
+ };
600
+ }),
601
+ };
602
+ const output = {
603
+ ok: Number(entitiesResult.summary?.failed ?? 0) === 0,
604
+ project: { name: displayName, externalKey: projectExternalKey, entityType: entityTypeOverride },
605
+ entities: entitiesResult.summary ?? {},
606
+ relationships: relsResult?.summary ?? { requested: 0, succeeded: 0, failed: 0 },
607
+ resolved: resolvedItems.length,
608
+ unresolved: unresolvedItems.length,
609
+ unresolvedSample: unresolvedItems.slice(0, 10).map((r) => r.input),
610
+ entityErrors: entitiesResult.errors ?? [],
611
+ relationshipErrors: relsResult?.errors ?? [],
612
+ enrichmentTask,
613
+ };
614
+ if (asJson) {
615
+ process.stdout.write(`${JSON.stringify(output, null, 2)}\n`);
616
+ if (!output.ok)
617
+ process.exitCode = 1;
618
+ return;
619
+ }
620
+ console.log(`\nDone.`);
621
+ console.log(` Entities : ${output.entities.succeeded ?? 0} written, ${output.entities.failed ?? 0} failed`);
622
+ console.log(` Relationships: ${output.relationships.succeeded ?? 0} written`);
623
+ if (unresolvedItems.length > 0) {
624
+ console.log(` Candidates : ${unresolvedItems.length} added to reference candidates`);
625
+ }
626
+ if (output.entityErrors.length > 0) {
627
+ console.log("\nEntity errors:");
628
+ for (const err of output.entityErrors) {
629
+ console.log(` ${err.externalKey}: ${err.error} — ${err.message}`);
630
+ }
631
+ }
632
+ // ─── Enrichment task ────────────────────────────────────────────────────────
633
+ console.log(enrichmentTask.instructions);
600
634
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexarch",
3
- "version": "0.1.25",
3
+ "version": "0.1.28",
4
4
  "description": "Connect AI coding tools to your Nexarch architecture workspace",
5
5
  "keywords": [
6
6
  "nexarch",