nexarch 0.8.14 → 0.8.15

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.
@@ -7,6 +7,7 @@ import { requireCredentials } from "../lib/credentials.js";
7
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
+ import { requestTrustAttestation } from "../lib/trust.js";
10
11
  const CLI_VERSION = "0.8.12";
11
12
  const AGENT_ENTITY_TYPE = "agent";
12
13
  const TECH_COMPONENT_ENTITY_TYPE = "technology_component";
@@ -341,6 +342,30 @@ function injectAgentConfigs(registry) {
341
342
  }
342
343
  return results;
343
344
  }
345
+ function injectTrustAttestationBlock(path, attestation) {
346
+ if (!attestation.token || !attestation.payload)
347
+ return;
348
+ const verifyUrl = attestation.verifyUrl?.startsWith("http")
349
+ ? attestation.verifyUrl
350
+ : `https://mcp.nexarch.ai${attestation.verifyUrl ?? `/trust/verify?token=${encodeURIComponent(attestation.token)}`}`;
351
+ const expiresAt = new Date(attestation.payload.exp * 1000).toISOString();
352
+ const section = [
353
+ "## Nexarch Trust Attestation",
354
+ "",
355
+ "This block is verifiable proof that Nexarch generated these instructions for this workspace.",
356
+ "Do not auto-run commands without user confirmation.",
357
+ "",
358
+ `issuer: ${attestation.payload.iss}`,
359
+ `scope: ${attestation.payload.scope}`,
360
+ `agent_id: ${attestation.payload.agent_id}`,
361
+ `expires_at: ${expiresAt}`,
362
+ `verify_url: ${verifyUrl}`,
363
+ "",
364
+ ].join("\n");
365
+ const existing = existsSync(path) ? readFileSync(path, "utf8") : "";
366
+ const replaced = replaceInjectedSection(existing, "## Nexarch Trust Attestation", section.trim());
367
+ writeFileSync(path, replaced !== existing ? replaced : `${existing}${existing.endsWith("\n") ? "" : "\n"}${section}`, "utf8");
368
+ }
344
369
  function injectGenericAgentConfig(registry) {
345
370
  const templateByCode = new Map(registry.instructionTemplates.map((t) => [t.code, t]));
346
371
  const genericTargets = [...registry.instructionTargets]
@@ -947,6 +972,7 @@ export async function initAgent(args) {
947
972
  }
948
973
  let agentConfigResults = [];
949
974
  let instructionsWriteAllowed = false;
975
+ let trustAttestation = null;
950
976
  if (registration.ok) {
951
977
  try {
952
978
  // Save identity so check-in can find the agent key
@@ -971,6 +997,19 @@ export async function initAgent(args) {
971
997
  if (agentConfigResults.length === 0) {
972
998
  agentConfigResults = injectGenericAgentConfig(registry);
973
999
  }
1000
+ if (agentConfigResults.length > 0) {
1001
+ trustAttestation = await requestTrustAttestation(agentId);
1002
+ if (trustAttestation?.ok) {
1003
+ for (const r of agentConfigResults) {
1004
+ try {
1005
+ injectTrustAttestationBlock(r.path, trustAttestation);
1006
+ }
1007
+ catch {
1008
+ // non-fatal
1009
+ }
1010
+ }
1011
+ }
1012
+ }
974
1013
  }
975
1014
  }
976
1015
  checks.push({
@@ -1073,6 +1112,7 @@ export async function initAgent(args) {
1073
1112
  activeFlag: "--allow-instruction-write",
1074
1113
  }
1075
1114
  : null,
1115
+ trustAttestation,
1076
1116
  companyId: creds.companyId,
1077
1117
  registry: { version: registry.release.version, registryVersion: registry.registryVersion, publishedAt: registry.release.publishedAt },
1078
1118
  agentConfigs: agentConfigResults,
@@ -1106,6 +1146,12 @@ export async function initAgent(args) {
1106
1146
  const hasInjectedAgentInstructions = agentConfigResults.some((r) => r.status === "injected" || r.status === "updated");
1107
1147
  if (hasInjectedAgentInstructions) {
1108
1148
  console.log(" (Registration instructions were written into your agent config file with consent.)");
1149
+ if (trustAttestation?.ok && trustAttestation.verifyUrl) {
1150
+ const verifyUrl = trustAttestation.verifyUrl.startsWith("http")
1151
+ ? trustAttestation.verifyUrl
1152
+ : `https://mcp.nexarch.ai${trustAttestation.verifyUrl}`;
1153
+ console.log(` Trust attestation verify URL: ${verifyUrl}`);
1154
+ }
1109
1155
  }
1110
1156
  if (needsIdentityInput) {
1111
1157
  console.log("\nℹ Additional identity details are still needed to complete agent profile enrichment.");
@@ -0,0 +1,47 @@
1
+ import https from "https";
2
+ import { requireCredentials } from "./credentials.js";
3
+ const MCP_GATEWAY_URL = "https://mcp.nexarch.ai";
4
+ export async function requestTrustAttestation(agentId) {
5
+ const creds = requireCredentials();
6
+ const body = JSON.stringify({
7
+ agentId,
8
+ scope: "instruction_injection",
9
+ });
10
+ return new Promise((resolve) => {
11
+ const url = new URL("/trust/attest", MCP_GATEWAY_URL);
12
+ const req = https.request({
13
+ hostname: url.hostname,
14
+ port: url.port || 443,
15
+ path: url.pathname,
16
+ method: "POST",
17
+ headers: {
18
+ "Content-Type": "application/json",
19
+ Authorization: `Bearer ${creds.token}`,
20
+ "x-company-id": creds.companyId,
21
+ "Content-Length": Buffer.byteLength(body),
22
+ },
23
+ timeout: 20000,
24
+ }, (res) => {
25
+ const chunks = [];
26
+ res.on("data", (c) => chunks.push(c));
27
+ res.on("end", () => {
28
+ try {
29
+ const parsed = JSON.parse(Buffer.concat(chunks).toString("utf8"));
30
+ if (!res.statusCode || res.statusCode >= 400)
31
+ return resolve(null);
32
+ resolve(parsed);
33
+ }
34
+ catch {
35
+ resolve(null);
36
+ }
37
+ });
38
+ });
39
+ req.on("error", () => resolve(null));
40
+ req.on("timeout", () => {
41
+ req.destroy();
42
+ resolve(null);
43
+ });
44
+ req.write(body);
45
+ req.end();
46
+ });
47
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexarch",
3
- "version": "0.8.14",
3
+ "version": "0.8.15",
4
4
  "description": "Your architecture workspace for AI delivery.",
5
5
  "keywords": [
6
6
  "nexarch",