nexarch 0.8.16 → 0.8.17

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