nexarch 0.1.20 → 0.1.22

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.
@@ -0,0 +1,80 @@
1
+ import process from "process";
2
+ import { requireCredentials } from "../lib/credentials.js";
3
+ import { callMcpTool } from "../lib/mcp.js";
4
+ function parseFlag(args, flag) {
5
+ return args.includes(flag);
6
+ }
7
+ function parseOptionValue(args, option) {
8
+ const idx = args.indexOf(option);
9
+ if (idx === -1)
10
+ return null;
11
+ const value = args[idx + 1];
12
+ if (!value || value.startsWith("--"))
13
+ return null;
14
+ return value;
15
+ }
16
+ function parseToolText(result) {
17
+ const text = result.content?.[0]?.text ?? "{}";
18
+ return JSON.parse(text);
19
+ }
20
+ export async function addRelationship(args) {
21
+ const asJson = parseFlag(args, "--json");
22
+ const fromKey = parseOptionValue(args, "--from");
23
+ const toKey = parseOptionValue(args, "--to");
24
+ const relType = parseOptionValue(args, "--type");
25
+ if (!fromKey) {
26
+ console.error("error: --from <externalKey> is required");
27
+ process.exit(1);
28
+ }
29
+ if (!toKey) {
30
+ console.error("error: --to <externalKey> is required");
31
+ process.exit(1);
32
+ }
33
+ if (!relType) {
34
+ console.error("error: --type <relationshipTypeCode> is required");
35
+ process.exit(1);
36
+ }
37
+ const creds = requireCredentials();
38
+ const mcpOpts = { companyId: creds.companyId };
39
+ const policiesRaw = await callMcpTool("nexarch_get_applied_policies", {}, mcpOpts);
40
+ const policies = parseToolText(policiesRaw);
41
+ const policyBundleHash = policies.policyBundleHash ?? null;
42
+ const nowIso = new Date().toISOString();
43
+ const agentContext = {
44
+ agentId: "nexarch-cli:add-relationship",
45
+ agentRunId: `add-relationship-${Date.now()}`,
46
+ repoRef: fromKey,
47
+ observedAt: nowIso,
48
+ source: "nexarch-cli",
49
+ model: "n/a",
50
+ provider: "n/a",
51
+ };
52
+ const policyContext = policyBundleHash
53
+ ? { policyBundleHash, alignmentSummary: { score: 1, violations: [], waivers: [] } }
54
+ : undefined;
55
+ const relationship = {
56
+ relationshipTypeCode: relType,
57
+ fromEntityExternalKey: fromKey,
58
+ toEntityExternalKey: toKey,
59
+ confidence: 1,
60
+ };
61
+ const raw = await callMcpTool("nexarch_upsert_relationships", { relationships: [relationship], agentContext, policyContext }, mcpOpts);
62
+ const result = parseToolText(raw);
63
+ if (asJson) {
64
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
65
+ if (Number(result.summary?.failed ?? 0) > 0)
66
+ process.exitCode = 1;
67
+ return;
68
+ }
69
+ const succeeded = result.summary?.succeeded ?? 0;
70
+ const failed = result.summary?.failed ?? 0;
71
+ if (failed > 0) {
72
+ console.error(`Failed to add relationship: ${fromKey} -[${relType}]-> ${toKey}`);
73
+ for (const err of result.errors ?? []) {
74
+ console.error(` ${err.error} — ${err.message}`);
75
+ }
76
+ process.exitCode = 1;
77
+ return;
78
+ }
79
+ console.log(`Added ${succeeded} relationship: ${fromKey} -[${relType}]-> ${toKey}`);
80
+ }
@@ -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.20";
7
+ const CLI_VERSION = "0.1.22";
8
8
  const AGENT_ENTITY_TYPE = "agent";
9
9
  const TECH_COMPONENT_ENTITY_TYPE = "technology_component";
10
10
  function parseFlag(args, flag) {
@@ -445,29 +445,41 @@ STEP 2 — Enrich the project entity. Run this command with the description you'
445
445
  --name "<proper product name from README>" \\
446
446
  --description "<2–4 sentence summary of what it does and why>"
447
447
  ${subPackages.length > 0 ? `
448
- STEP 3 — Register each sub-application as its own entity.
449
- The scanner found ${subPackages.length} workspace package(s). For each one, read its
450
- README / package.json description, then run:
448
+ STEP 3 — Classify and register each sub-package as its own entity.
449
+ The scanner found ${subPackages.length} workspace package(s):
451
450
 
452
- Sub-packages detected:
453
451
  ${subPackages.map((sp) => ` • ${sp.name} (${sp.relativePath})`).join("\n")}
454
452
 
455
- For each sub-package run:
453
+ For each one, READ its package.json and any README to understand what it actually is,
454
+ then choose the correct entity type and subtype before running update-entity:
456
455
 
457
- npx nexarch update-entity \\
458
- --key "application:<slugified-package-name>" \\
459
- --entity-type "application" \\
460
- --subtype "app_custom_built" \\
461
- --name "<sub-app name>" \\
462
- --description "<what this sub-app does>"
456
+ CLASSIFICATION GUIDE pick the best fit:
457
+ Deployable web app (has a dev/start/build script, runs in a browser or as a server)
458
+ --entity-type application --subtype app_web
459
+ Deployable background service, worker, or data pipeline (runs as a process, no UI)
460
+ --entity-type application --subtype app_custom_built (or app_integration_service for crawlers/ETL)
461
+ Shared internal library or package (imported by other packages, not deployed on its own)
462
+ → --entity-type technology_component --subtype tech_library
463
+ Shared UI component library
464
+ → --entity-type technology_component --subtype tech_framework
465
+ Type definitions or utility package with no runtime
466
+ → --entity-type technology_component --subtype tech_library
467
+
468
+ For each sub-package, run:
463
469
 
464
- Then wire it to the parent project:
470
+ npx nexarch update-entity \\
471
+ --key "<entity-type>:<slugified-package-name>" \\
472
+ --entity-type "<chosen entity type>" \\
473
+ --subtype "<chosen subtype>" \\
474
+ --name "<human readable name>" \\
475
+ --description "<what this package does and its role in the project>"
465
476
 
466
- npx nexarch add-relationship \\
467
- --from "application:<slugified-package-name>" \\
468
- --to "${projectExternalKey}" \\
469
- --type "part_of"
477
+ Then wire it to the parent project using the appropriate relationship:
478
+ Deployable apps → relationship type: part_of
479
+ Shared libraries → relationship type: depends_on (parent depends on the library)
470
480
 
471
- (Note: add-relationship is coming soon — skip if not yet available)
481
+ Relationship type reference:
482
+ part_of — deployable sub-app is structurally part of the parent product
483
+ depends_on — parent product depends on a shared library at runtime
472
484
  ` : ""}`);
473
485
  }
package/dist/index.js CHANGED
@@ -12,6 +12,7 @@ import { initAgent } from "./commands/init-agent.js";
12
12
  import { agentIdentify } from "./commands/agent-identify.js";
13
13
  import { initProject } from "./commands/init-project.js";
14
14
  import { updateEntity } from "./commands/update-entity.js";
15
+ import { addRelationship } from "./commands/add-relationship.js";
15
16
  const [, , command, ...args] = process.argv;
16
17
  const commands = {
17
18
  login,
@@ -24,6 +25,7 @@ const commands = {
24
25
  "agent-identify": agentIdentify,
25
26
  "init-project": initProject,
26
27
  "update-entity": updateEntity,
28
+ "add-relationship": addRelationship,
27
29
  };
28
30
  async function main() {
29
31
  if (command === "agent") {
@@ -93,6 +95,12 @@ Usage:
93
95
  --entity-type <code> (default: application)
94
96
  --subtype <code>
95
97
  --json
98
+ nexarch add-relationship
99
+ Add a relationship between two existing graph entities.
100
+ Options: --from <externalKey> (required)
101
+ --to <externalKey> (required)
102
+ --type <code> (required, e.g. part_of, depends_on)
103
+ --json
96
104
  `);
97
105
  process.exit(command ? 1 : 0);
98
106
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexarch",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "description": "Connect AI coding tools to your Nexarch architecture workspace",
5
5
  "keywords": [
6
6
  "nexarch",