nexarch 0.8.16 → 0.8.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.
@@ -8,7 +8,7 @@ import { fetchAgentRegistryOrThrow } from "../lib/agent-registry.js";
8
8
  import { callMcpTool, mcpInitialize, mcpListTools } from "../lib/mcp.js";
9
9
  import { buildVersionAttributes } from "../lib/version-normalization.js";
10
10
  import { requestTrustAttestation } from "../lib/trust.js";
11
- const CLI_VERSION = "0.8.16";
11
+ const CLI_VERSION = "0.8.19";
12
12
  const AGENT_ENTITY_TYPE = "agent";
13
13
  const TECH_COMPONENT_ENTITY_TYPE = "technology_component";
14
14
  function parseFlag(args, flag) {
@@ -287,6 +287,28 @@ After running, confirm \`"ok": true\` in the JSON output. No further action is n
287
287
  writeFileSync(filePath, content, "utf8");
288
288
  return filePath;
289
289
  }
290
+ function managedMarkers(key) {
291
+ return {
292
+ start: `<!-- nexarch:${key}:start -->`,
293
+ end: `<!-- nexarch:${key}:end -->`,
294
+ };
295
+ }
296
+ function wrapManagedSection(key, body) {
297
+ const markers = managedMarkers(key);
298
+ return `${markers.start}\n${body.trim()}\n${markers.end}`;
299
+ }
300
+ function replaceManagedSection(existing, key, body) {
301
+ const markers = managedMarkers(key);
302
+ const escapedStart = markers.start.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
303
+ const escapedEnd = markers.end.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
304
+ const managedRegex = new RegExp(`${escapedStart}[\\s\\S]*?${escapedEnd}\\s*`, "gm");
305
+ if (!managedRegex.test(existing))
306
+ return existing;
307
+ const canonicalBlock = wrapManagedSection(key, body);
308
+ const stripped = existing.replace(managedRegex, "").trimEnd();
309
+ const rebuilt = `${stripped}${stripped ? "\n\n" : ""}${canonicalBlock}\n`;
310
+ return rebuilt;
311
+ }
290
312
  function replaceInjectedSection(existing, sectionHeading, sectionBody) {
291
313
  const escapedHeading = sectionHeading.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
292
314
  const blockRegex = new RegExp(`^${escapedHeading}[\\t ]*\\n[\\s\\S]*?(?=^##\\s|$)`, "gm");
@@ -315,33 +337,37 @@ function injectAgentConfigs(registry) {
315
337
  const sectionBody = template.body.trim();
316
338
  const sectionHeading = target.sectionHeading ?? "## Nexarch Agent Registration";
317
339
  const sectionMarker = target.sectionMarker ?? sectionHeading;
340
+ const managedBody = wrapManagedSection("agent-registration", sectionBody);
318
341
  if (target.insertionMode === "replace_section") {
319
- let replaced = replaceInjectedSection(existing, sectionHeading, sectionBody);
342
+ let replaced = replaceManagedSection(existing, "agent-registration", sectionBody);
343
+ if (replaced === existing) {
344
+ replaced = replaceInjectedSection(existing, sectionHeading, managedBody);
345
+ }
320
346
  if (replaced === existing && existing.includes(sectionMarker)) {
321
347
  const markerIndex = existing.indexOf(sectionMarker);
322
348
  const before = existing.slice(0, markerIndex).replace(/\s*$/, "\n\n");
323
- replaced = `${before}${sectionBody}\n`;
349
+ replaced = `${before}${managedBody}\n`;
324
350
  }
325
351
  if (replaced !== existing) {
326
352
  writeFileSync(filePath, replaced, "utf8");
327
353
  results.push({ path: filePath, status: "updated" });
328
354
  }
329
- else if (existing.includes(sectionBody)) {
355
+ else if (existing.includes(managedBody) || existing.includes(sectionBody)) {
330
356
  results.push({ path: filePath, status: "already_present" });
331
357
  }
332
358
  else {
333
359
  const separator = existing.endsWith("\n") ? "" : "\n";
334
- writeFileSync(filePath, existing + separator + sectionBody + "\n", "utf8");
360
+ writeFileSync(filePath, existing + separator + managedBody + "\n", "utf8");
335
361
  results.push({ path: filePath, status: "injected" });
336
362
  }
337
363
  continue;
338
364
  }
339
- if (existing.includes(sectionBody)) {
365
+ if (existing.includes(managedBody) || existing.includes(sectionBody)) {
340
366
  results.push({ path: filePath, status: "already_present" });
341
367
  }
342
368
  else {
343
369
  const separator = existing.endsWith("\n") ? "" : "\n";
344
- const next = existing + separator + sectionBody + "\n";
370
+ const next = existing + separator + managedBody + "\n";
345
371
  writeFileSync(filePath, next, "utf8");
346
372
  results.push({ path: filePath, status: "injected" });
347
373
  }
@@ -370,8 +396,29 @@ function injectTrustAttestationBlock(path, attestation) {
370
396
  "",
371
397
  ].join("\n");
372
398
  const existing = existsSync(path) ? readFileSync(path, "utf8") : "";
373
- const replaced = replaceInjectedSection(existing, "## Nexarch Trust Attestation", section.trim());
374
- writeFileSync(path, replaced !== existing ? replaced : `${existing}${existing.endsWith("\n") ? "" : "\n"}${section}`, "utf8");
399
+ const managed = wrapManagedSection("trust-attestation", section.trim());
400
+ let replaced = replaceManagedSection(existing, "trust-attestation", section.trim());
401
+ if (replaced === existing) {
402
+ replaced = replaceInjectedSection(existing, "## Nexarch Trust Attestation", managed);
403
+ }
404
+ writeFileSync(path, replaced !== existing ? replaced : `${existing}${existing.endsWith("\n") ? "" : "\n"}${managed}\n`, "utf8");
405
+ }
406
+ function injectTrustAttestationUnavailableBlock(path, reason) {
407
+ const section = [
408
+ "## Nexarch Trust Attestation",
409
+ "",
410
+ "Trust attestation was requested but is currently unavailable.",
411
+ `status: unavailable (${reason})`,
412
+ "action: check MCP gateway TRUST_ATTESTATION_SECRET and restart gateway",
413
+ "",
414
+ ].join("\n");
415
+ const existing = existsSync(path) ? readFileSync(path, "utf8") : "";
416
+ const managed = wrapManagedSection("trust-attestation", section.trim());
417
+ let replaced = replaceManagedSection(existing, "trust-attestation", section.trim());
418
+ if (replaced === existing) {
419
+ replaced = replaceInjectedSection(existing, "## Nexarch Trust Attestation", managed);
420
+ }
421
+ writeFileSync(path, replaced !== existing ? replaced : `${existing}${existing.endsWith("\n") ? "" : "\n"}${managed}\n`, "utf8");
375
422
  }
376
423
  function injectGenericAgentConfig(registry) {
377
424
  const templateByCode = new Map(registry.instructionTemplates.map((t) => [t.code, t]));
@@ -385,20 +432,30 @@ function injectGenericAgentConfig(registry) {
385
432
  const filePath = join(process.cwd(), target.filePathPattern);
386
433
  const sectionBody = template.body.trim();
387
434
  const sectionHeading = target.sectionHeading ?? "## Nexarch Agent Registration";
435
+ const managedBody = wrapManagedSection("agent-registration", sectionBody);
388
436
  if (!existsSync(filePath)) {
389
- writeFileSync(filePath, `${sectionBody}\n`, "utf8");
437
+ writeFileSync(filePath, `${managedBody}\n`, "utf8");
390
438
  return [{ path: filePath, status: "injected" }];
391
439
  }
392
440
  const existing = readFileSync(filePath, "utf8");
393
441
  if (target.insertionMode === "replace_section") {
394
- const replaced = replaceInjectedSection(existing, sectionHeading, sectionBody);
442
+ let replaced = replaceManagedSection(existing, "agent-registration", sectionBody);
443
+ if (replaced === existing) {
444
+ replaced = replaceInjectedSection(existing, sectionHeading, managedBody);
445
+ }
395
446
  if (replaced !== existing) {
396
447
  writeFileSync(filePath, replaced, "utf8");
397
448
  return [{ path: filePath, status: "updated" }];
398
449
  }
450
+ if (existing.includes(managedBody) || existing.includes(sectionBody)) {
451
+ return [{ path: filePath, status: "already_present" }];
452
+ }
453
+ }
454
+ if (existing.includes(managedBody) || existing.includes(sectionBody)) {
455
+ return [{ path: filePath, status: "already_present" }];
399
456
  }
400
457
  const separator = existing.endsWith("\n") ? "" : "\n";
401
- writeFileSync(filePath, existing + separator + sectionBody + "\n", "utf8");
458
+ writeFileSync(filePath, existing + separator + managedBody + "\n", "utf8");
402
459
  return [{ path: filePath, status: "injected" }];
403
460
  }
404
461
  const fallbackTemplate = templateByCode.get("nexarch_agent_registration_v1") ?? registry.instructionTemplates[0];
@@ -406,19 +463,26 @@ function injectGenericAgentConfig(registry) {
406
463
  return [];
407
464
  const fallbackPath = join(process.cwd(), "AGENTS.md");
408
465
  const sectionBody = fallbackTemplate.body.trim();
466
+ const managedBody = wrapManagedSection("agent-registration", sectionBody);
409
467
  if (!existsSync(fallbackPath)) {
410
- writeFileSync(fallbackPath, `${sectionBody}\n`, "utf8");
468
+ writeFileSync(fallbackPath, `${managedBody}\n`, "utf8");
411
469
  return [{ path: fallbackPath, status: "injected" }];
412
470
  }
413
471
  const existing = readFileSync(fallbackPath, "utf8");
414
472
  const sectionHeading = "## Nexarch Agent Registration";
415
- const replaced = replaceInjectedSection(existing, sectionHeading, sectionBody);
473
+ let replaced = replaceManagedSection(existing, "agent-registration", sectionBody);
474
+ if (replaced === existing) {
475
+ replaced = replaceInjectedSection(existing, sectionHeading, managedBody);
476
+ }
416
477
  if (replaced !== existing) {
417
478
  writeFileSync(fallbackPath, replaced, "utf8");
418
479
  return [{ path: fallbackPath, status: "updated" }];
419
480
  }
481
+ if (existing.includes(managedBody) || existing.includes(sectionBody)) {
482
+ return [{ path: fallbackPath, status: "already_present" }];
483
+ }
420
484
  const separator = existing.endsWith("\n") ? "" : "\n";
421
- writeFileSync(fallbackPath, existing + separator + sectionBody + "\n", "utf8");
485
+ writeFileSync(fallbackPath, existing + separator + managedBody + "\n", "utf8");
422
486
  return [{ path: fallbackPath, status: "injected" }];
423
487
  }
424
488
  export async function initAgent(args) {
@@ -1008,15 +1072,18 @@ export async function initAgent(args) {
1008
1072
  if (agentConfigResults.length > 0) {
1009
1073
  trustAttestationAttempted = true;
1010
1074
  trustAttestation = await requestTrustAttestation(agentId);
1011
- if (trustAttestation.ok) {
1012
- for (const r of agentConfigResults) {
1013
- try {
1075
+ for (const r of agentConfigResults) {
1076
+ try {
1077
+ if (trustAttestation.ok) {
1014
1078
  injectTrustAttestationBlock(r.path, trustAttestation);
1015
1079
  }
1016
- catch {
1017
- // non-fatal
1080
+ else {
1081
+ injectTrustAttestationUnavailableBlock(r.path, trustAttestation.reason ?? "unknown");
1018
1082
  }
1019
1083
  }
1084
+ catch {
1085
+ // non-fatal
1086
+ }
1020
1087
  }
1021
1088
  }
1022
1089
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexarch",
3
- "version": "0.8.16",
3
+ "version": "0.8.19",
4
4
  "description": "Your architecture workspace for AI delivery.",
5
5
  "keywords": [
6
6
  "nexarch",