clawdentity 0.0.16 → 0.0.18

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.
package/dist/bin.js CHANGED
@@ -17084,7 +17084,8 @@ var FILE_MODE = 384;
17084
17084
  var ENV_KEY_MAP = {
17085
17085
  registryUrl: "CLAWDENTITY_REGISTRY_URL",
17086
17086
  proxyUrl: "CLAWDENTITY_PROXY_URL",
17087
- apiKey: "CLAWDENTITY_API_KEY"
17087
+ apiKey: "CLAWDENTITY_API_KEY",
17088
+ humanName: "CLAWDENTITY_HUMAN_NAME"
17088
17089
  };
17089
17090
  var LEGACY_ENV_KEY_MAP = {
17090
17091
  registryUrl: ["CLAWDENTITY_REGISTRY"]
@@ -17111,6 +17112,9 @@ var normalizeConfig = (raw) => {
17111
17112
  if (typeof raw.apiKey === "string" && raw.apiKey.length > 0) {
17112
17113
  config2.apiKey = raw.apiKey;
17113
17114
  }
17115
+ if (typeof raw.humanName === "string" && raw.humanName.length > 0) {
17116
+ config2.humanName = raw.humanName;
17117
+ }
17114
17118
  return config2;
17115
17119
  };
17116
17120
  var getConfigDir = () => join2(homedir(), CONFIG_DIR);
@@ -18536,7 +18540,8 @@ var logger5 = createLogger({ service: "cli", module: "config" });
18536
18540
  var VALID_KEYS = [
18537
18541
  "registryUrl",
18538
18542
  "proxyUrl",
18539
- "apiKey"
18543
+ "apiKey",
18544
+ "humanName"
18540
18545
  ];
18541
18546
  var isValidConfigKey = (value) => {
18542
18547
  return VALID_KEYS.includes(value);
@@ -18651,7 +18656,7 @@ var createConfigCommand = (dependencies = {}) => {
18651
18656
 
18652
18657
  // src/commands/connector.ts
18653
18658
  import { execFile as execFileCallback } from "child_process";
18654
- import { mkdir as mkdir4, readFile as readFile3, rm, writeFile as writeFile4 } from "fs/promises";
18659
+ import { mkdir as mkdir4, readFile as readFile4, rm, writeFile as writeFile4 } from "fs/promises";
18655
18660
  import { homedir as homedir2 } from "os";
18656
18661
  import { dirname as dirname3, join as join5 } from "path";
18657
18662
  import { fileURLToPath } from "url";
@@ -19320,7 +19325,7 @@ var ConnectorClient = class {
19320
19325
 
19321
19326
  // ../../packages/connector/src/runtime.ts
19322
19327
  import { randomBytes as randomBytes2 } from "crypto";
19323
- import { mkdir as mkdir3, rename as rename2, writeFile as writeFile3 } from "fs/promises";
19328
+ import { mkdir as mkdir3, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "fs/promises";
19324
19329
  import {
19325
19330
  createServer
19326
19331
  } from "http";
@@ -19497,6 +19502,63 @@ async function writeRegistryAuthAtomic(input) {
19497
19502
  `, "utf8");
19498
19503
  await rename2(tmpPath, targetPath);
19499
19504
  }
19505
+ function parseRegistryAuthFromDisk(payload) {
19506
+ if (!isRecord5(payload)) {
19507
+ return void 0;
19508
+ }
19509
+ const tokenType = payload.tokenType;
19510
+ const accessToken = payload.accessToken;
19511
+ const accessExpiresAt = payload.accessExpiresAt;
19512
+ const refreshToken = payload.refreshToken;
19513
+ const refreshExpiresAt = payload.refreshExpiresAt;
19514
+ if (tokenType !== "Bearer" || typeof accessToken !== "string" || typeof accessExpiresAt !== "string" || typeof refreshToken !== "string" || typeof refreshExpiresAt !== "string") {
19515
+ return void 0;
19516
+ }
19517
+ return {
19518
+ tokenType,
19519
+ accessToken,
19520
+ accessExpiresAt,
19521
+ refreshToken,
19522
+ refreshExpiresAt
19523
+ };
19524
+ }
19525
+ async function readRegistryAuthFromDisk(input) {
19526
+ const authPath = join4(
19527
+ input.configDir,
19528
+ AGENTS_DIR_NAME2,
19529
+ input.agentName,
19530
+ REGISTRY_AUTH_FILENAME
19531
+ );
19532
+ let raw;
19533
+ try {
19534
+ raw = await readFile3(authPath, "utf8");
19535
+ } catch (error48) {
19536
+ if (error48 && typeof error48 === "object" && "code" in error48 && error48.code === "ENOENT") {
19537
+ return void 0;
19538
+ }
19539
+ input.logger.warn("connector.runtime.registry_auth_read_failed", {
19540
+ authPath,
19541
+ reason: error48 instanceof Error ? error48.message : "unknown"
19542
+ });
19543
+ return void 0;
19544
+ }
19545
+ let parsed;
19546
+ try {
19547
+ parsed = JSON.parse(raw);
19548
+ } catch {
19549
+ input.logger.warn("connector.runtime.registry_auth_invalid_json", {
19550
+ authPath
19551
+ });
19552
+ return void 0;
19553
+ }
19554
+ const auth = parseRegistryAuthFromDisk(parsed);
19555
+ if (auth === void 0) {
19556
+ input.logger.warn("connector.runtime.registry_auth_invalid_shape", {
19557
+ authPath
19558
+ });
19559
+ }
19560
+ return auth;
19561
+ }
19500
19562
  async function readRequestJson(req) {
19501
19563
  const chunks = [];
19502
19564
  let totalBytes = 0;
@@ -19560,7 +19622,25 @@ async function startConnectorRuntime(input) {
19560
19622
  parseRequiredString(input.credentials.secretKey, "secretKey")
19561
19623
  );
19562
19624
  let currentAuth = toInitialAuthBundle(input.credentials);
19625
+ const syncAuthFromDisk = async () => {
19626
+ const diskAuth = await readRegistryAuthFromDisk({
19627
+ configDir: input.configDir,
19628
+ agentName: input.agentName,
19629
+ logger: logger12
19630
+ });
19631
+ if (!diskAuth) {
19632
+ return;
19633
+ }
19634
+ if (diskAuth.accessToken === currentAuth.accessToken && diskAuth.accessExpiresAt === currentAuth.accessExpiresAt && diskAuth.refreshToken === currentAuth.refreshToken && diskAuth.refreshExpiresAt === currentAuth.refreshExpiresAt) {
19635
+ return;
19636
+ }
19637
+ currentAuth = diskAuth;
19638
+ logger12.info("connector.runtime.registry_auth_synced", {
19639
+ agentName: input.agentName
19640
+ });
19641
+ };
19563
19642
  const refreshCurrentAuthIfNeeded = async () => {
19643
+ await syncAuthFromDisk();
19564
19644
  if (!shouldRefreshAccessToken(currentAuth, Date.now())) {
19565
19645
  return;
19566
19646
  }
@@ -19604,6 +19684,7 @@ async function startConnectorRuntime(input) {
19604
19684
  const statusPath = DEFAULT_CONNECTOR_STATUS_PATH;
19605
19685
  const outboundUrl = new URL(outboundPath, outboundBaseUrl).toString();
19606
19686
  const relayToPeer = async (request) => {
19687
+ await syncAuthFromDisk();
19607
19688
  const peerUrl = new URL(request.peerProxyUrl);
19608
19689
  const body = JSON.stringify(request.payload ?? {});
19609
19690
  const refreshKey = `${REFRESH_SINGLE_FLIGHT_PREFIX}:${input.configDir}:${input.agentName}`;
@@ -19648,7 +19729,10 @@ async function startConnectorRuntime(input) {
19648
19729
  await executeWithAgentAuthRefreshRetry({
19649
19730
  key: refreshKey,
19650
19731
  shouldRetry: isRetryableRelayAuthError,
19651
- getAuth: async () => currentAuth,
19732
+ getAuth: async () => {
19733
+ await syncAuthFromDisk();
19734
+ return currentAuth;
19735
+ },
19652
19736
  persistAuth: async (nextAuth) => {
19653
19737
  currentAuth = nextAuth;
19654
19738
  await writeRegistryAuthAtomic({
@@ -20395,7 +20479,7 @@ async function uninstallConnectorServiceForAgent(agentName, commandOptions = {},
20395
20479
  async function startConnectorForAgent(agentName, commandOptions = {}, dependencies = {}) {
20396
20480
  const resolveConfigImpl = dependencies.resolveConfigImpl ?? resolveConfig;
20397
20481
  const getConfigDirImpl = dependencies.getConfigDirImpl ?? getConfigDir;
20398
- const readFileImpl = dependencies.readFileImpl ?? ((path, encoding) => readFile3(path, encoding));
20482
+ const readFileImpl = dependencies.readFileImpl ?? ((path, encoding) => readFile4(path, encoding));
20399
20483
  const fetchImpl = dependencies.fetchImpl ?? globalThis.fetch;
20400
20484
  const loadConnectorModule = dependencies.loadConnectorModule ?? loadDefaultConnectorModule;
20401
20485
  const configDir = getConfigDirImpl();
@@ -20783,11 +20867,20 @@ function parseInviteRedeemResponse(payload) {
20783
20867
  }
20784
20868
  const apiKeyId = parseNonEmptyString7(apiKeySource.id);
20785
20869
  const apiKeyName = parseNonEmptyString7(apiKeySource.name);
20870
+ const humanSource = isRecord7(payload.human) ? payload.human : void 0;
20871
+ const humanName = parseNonEmptyString7(humanSource?.displayName);
20786
20872
  const proxyUrl = parseNonEmptyString7(payload.proxyUrl);
20873
+ if (humanName.length === 0) {
20874
+ throw createCliError5(
20875
+ "CLI_INVITE_REDEEM_INVALID_RESPONSE",
20876
+ "Invite redeem response is invalid"
20877
+ );
20878
+ }
20787
20879
  return {
20788
20880
  apiKeyToken,
20789
20881
  apiKeyId: apiKeyId.length > 0 ? apiKeyId : void 0,
20790
20882
  apiKeyName: apiKeyName.length > 0 ? apiKeyName : void 0,
20883
+ humanName,
20791
20884
  proxyUrl
20792
20885
  };
20793
20886
  }
@@ -20842,6 +20935,14 @@ async function redeemInvite(code, options, dependencies = {}) {
20842
20935
  "Invite code is required"
20843
20936
  );
20844
20937
  }
20938
+ const displayName = parseNonEmptyString7(options.displayName);
20939
+ if (displayName.length === 0) {
20940
+ throw createCliError5(
20941
+ "CLI_INVITE_REDEEM_DISPLAY_NAME_REQUIRED",
20942
+ "Display name is required. Pass --display-name <name>."
20943
+ );
20944
+ }
20945
+ const apiKeyName = parseNonEmptyString7(options.apiKeyName);
20845
20946
  const runtime = await resolveInviteRuntime(options.registryUrl, dependencies);
20846
20947
  const response = await executeInviteRequest({
20847
20948
  fetchImpl: runtime.fetchImpl,
@@ -20851,7 +20952,11 @@ async function redeemInvite(code, options, dependencies = {}) {
20851
20952
  headers: {
20852
20953
  "content-type": "application/json"
20853
20954
  },
20854
- body: JSON.stringify({ code: inviteCode })
20955
+ body: JSON.stringify({
20956
+ code: inviteCode,
20957
+ displayName,
20958
+ apiKeyName: apiKeyName.length > 0 ? apiKeyName : void 0
20959
+ })
20855
20960
  }
20856
20961
  });
20857
20962
  const responseBody = await parseJsonResponse5(response);
@@ -20871,12 +20976,13 @@ async function redeemInvite(code, options, dependencies = {}) {
20871
20976
  registryUrl: runtime.registryUrl
20872
20977
  };
20873
20978
  }
20874
- async function persistRedeemConfig(registryUrl, apiKeyToken, proxyUrl, dependencies = {}) {
20979
+ async function persistRedeemConfig(registryUrl, apiKeyToken, proxyUrl, humanName, dependencies = {}) {
20875
20980
  const setConfigValueImpl = dependencies.setConfigValueImpl ?? setConfigValue;
20876
20981
  try {
20877
20982
  await setConfigValueImpl("registryUrl", registryUrl);
20878
20983
  await setConfigValueImpl("apiKey", apiKeyToken);
20879
20984
  await setConfigValueImpl("proxyUrl", proxyUrl);
20985
+ await setConfigValueImpl("humanName", humanName);
20880
20986
  } catch (error48) {
20881
20987
  logger7.warn("cli.invite_redeem_config_persist_failed", {
20882
20988
  errorName: error48 instanceof Error ? error48.name : "unknown"
@@ -20910,7 +21016,10 @@ var createInviteCommand = (dependencies = {}) => {
20910
21016
  }
20911
21017
  )
20912
21018
  );
20913
- inviteCommand.command("redeem <code>").description("Redeem a registry invite code and store PAT locally").option("--registry-url <url>", "Override registry URL").action(
21019
+ inviteCommand.command("redeem <code>").description("Redeem a registry invite code and store PAT locally").requiredOption(
21020
+ "--display-name <name>",
21021
+ "Human display name used for onboarding"
21022
+ ).option("--api-key-name <name>", "Optional API key label").option("--registry-url <url>", "Override registry URL").action(
20914
21023
  withErrorHandling(
20915
21024
  "invite redeem",
20916
21025
  async (code, options) => {
@@ -20918,9 +21027,11 @@ var createInviteCommand = (dependencies = {}) => {
20918
21027
  logger7.info("cli.invite_redeemed", {
20919
21028
  apiKeyId: result.apiKeyId,
20920
21029
  apiKeyName: result.apiKeyName,
21030
+ humanName: result.humanName,
20921
21031
  registryUrl: result.registryUrl
20922
21032
  });
20923
21033
  writeStdoutLine("Invite redeemed");
21034
+ writeStdoutLine(`Human name: ${result.humanName}`);
20924
21035
  if (result.apiKeyName) {
20925
21036
  writeStdoutLine(`API key name: ${result.apiKeyName}`);
20926
21037
  }
@@ -20930,6 +21041,7 @@ var createInviteCommand = (dependencies = {}) => {
20930
21041
  result.registryUrl,
20931
21042
  result.apiKeyToken,
20932
21043
  result.proxyUrl,
21044
+ result.humanName,
20933
21045
  dependencies
20934
21046
  );
20935
21047
  writeStdoutLine("API key saved to local config");
@@ -20943,7 +21055,7 @@ var createInviteCommand = (dependencies = {}) => {
20943
21055
  import { spawn } from "child_process";
20944
21056
  import { randomBytes as randomBytes3 } from "crypto";
20945
21057
  import { existsSync } from "fs";
20946
- import { chmod as chmod3, copyFile, mkdir as mkdir5, readFile as readFile4, writeFile as writeFile5 } from "fs/promises";
21058
+ import { chmod as chmod3, copyFile, mkdir as mkdir5, readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
20947
21059
  import { homedir as homedir3 } from "os";
20948
21060
  import { dirname as dirname4, join as join6, resolve as resolvePath } from "path";
20949
21061
  import { fileURLToPath as fileURLToPath2 } from "url";
@@ -21034,11 +21146,11 @@ function parseNonEmptyString8(value, label) {
21034
21146
  }
21035
21147
  return trimmed;
21036
21148
  }
21037
- function parseOptionalName(value) {
21149
+ function parseOptionalProfileName(value, label) {
21038
21150
  if (value === void 0) {
21039
21151
  return void 0;
21040
21152
  }
21041
- return parseNonEmptyString8(value, "name");
21153
+ return parseNonEmptyString8(value, label);
21042
21154
  }
21043
21155
  function parsePeerAlias(value) {
21044
21156
  const alias = parseNonEmptyString8(value, "peer alias");
@@ -21212,7 +21324,7 @@ function resolveTransformPeersPath(openclawDir) {
21212
21324
  return join6(openclawDir, "hooks", "transforms", RELAY_PEERS_FILE_NAME);
21213
21325
  }
21214
21326
  async function readJsonFile(filePath) {
21215
- const raw = await readFile4(filePath, "utf8");
21327
+ const raw = await readFile5(filePath, "utf8");
21216
21328
  try {
21217
21329
  return JSON.parse(raw);
21218
21330
  } catch {
@@ -21230,7 +21342,7 @@ async function ensureLocalAgentCredentials(homeDir, agentName) {
21230
21342
  for (const filePath of requiredFiles) {
21231
21343
  let content;
21232
21344
  try {
21233
- content = await readFile4(filePath, "utf8");
21345
+ content = await readFile5(filePath, "utf8");
21234
21346
  } catch (error48) {
21235
21347
  if (getErrorCode2(error48) === "ENOENT") {
21236
21348
  throw createCliError6(
@@ -21295,12 +21407,13 @@ async function loadPeersConfig(peersPath) {
21295
21407
  }
21296
21408
  const did = parseAgentDid2(value.did, `Peer ${normalizedAlias} did`);
21297
21409
  const proxyUrl = parseProxyUrl(value.proxyUrl);
21298
- const name = parseOptionalName(value.name);
21299
- if (name === void 0) {
21410
+ const agentName = parseOptionalProfileName(value.agentName, "agentName");
21411
+ const humanName = parseOptionalProfileName(value.humanName, "humanName");
21412
+ if (agentName === void 0 && humanName === void 0) {
21300
21413
  peers[normalizedAlias] = { did, proxyUrl };
21301
21414
  continue;
21302
21415
  }
21303
- peers[normalizedAlias] = { did, proxyUrl, name };
21416
+ peers[normalizedAlias] = { did, proxyUrl, agentName, humanName };
21304
21417
  }
21305
21418
  return { peers };
21306
21419
  }
@@ -21524,7 +21637,7 @@ function resolveConnectorPidPath(homeDir, agentName) {
21524
21637
  }
21525
21638
  async function readConnectorPidFile(pidPath) {
21526
21639
  try {
21527
- const raw = (await readFile4(pidPath, "utf8")).trim();
21640
+ const raw = (await readFile5(pidPath, "utf8")).trim();
21528
21641
  if (raw.length === 0) {
21529
21642
  return void 0;
21530
21643
  }
@@ -22039,7 +22152,7 @@ async function runOpenclawDoctor(options = {}) {
22039
22152
  const selectedAgentPath = resolveOpenclawAgentNamePath(homeDir);
22040
22153
  let selectedAgentName;
22041
22154
  try {
22042
- const selectedAgentRaw = await readFile4(selectedAgentPath, "utf8");
22155
+ const selectedAgentRaw = await readFile5(selectedAgentPath, "utf8");
22043
22156
  selectedAgentName = assertValidAgentName(selectedAgentRaw.trim());
22044
22157
  checks.push(
22045
22158
  toDoctorCheck({
@@ -22162,9 +22275,9 @@ async function runOpenclawDoctor(options = {}) {
22162
22275
  const relayTransformRuntimePath = resolveTransformRuntimePath(openclawDir);
22163
22276
  const relayTransformPeersPath = resolveTransformPeersPath(openclawDir);
22164
22277
  try {
22165
- const transformContents = await readFile4(transformTargetPath, "utf8");
22166
- const runtimeContents = await readFile4(relayTransformRuntimePath, "utf8");
22167
- const peersSnapshotContents = await readFile4(
22278
+ const transformContents = await readFile5(transformTargetPath, "utf8");
22279
+ const runtimeContents = await readFile5(relayTransformRuntimePath, "utf8");
22280
+ const peersSnapshotContents = await readFile5(
22168
22281
  relayTransformPeersPath,
22169
22282
  "utf8"
22170
22283
  );
@@ -22873,7 +22986,7 @@ import {
22873
22986
  chmod as chmod4,
22874
22987
  mkdir as mkdir6,
22875
22988
  readdir,
22876
- readFile as readFile5,
22989
+ readFile as readFile6,
22877
22990
  unlink as unlink2,
22878
22991
  writeFile as writeFile6
22879
22992
  } from "fs/promises";
@@ -22899,6 +23012,7 @@ var FILE_MODE4 = 384;
22899
23012
  var PEER_ALIAS_PATTERN2 = /^[a-zA-Z0-9._-]+$/;
22900
23013
  var DEFAULT_STATUS_WAIT_SECONDS = 300;
22901
23014
  var DEFAULT_STATUS_POLL_INTERVAL_SECONDS = 3;
23015
+ var MAX_PROFILE_NAME_LENGTH = 64;
22902
23016
  var isRecord9 = (value) => {
22903
23017
  return typeof value === "object" && value !== null;
22904
23018
  };
@@ -22915,6 +23029,49 @@ function parseNonEmptyString9(value) {
22915
23029
  }
22916
23030
  return value.trim();
22917
23031
  }
23032
+ function hasControlChars2(value) {
23033
+ for (let index = 0; index < value.length; index += 1) {
23034
+ const code = value.charCodeAt(index);
23035
+ if (code <= 31 || code === 127) {
23036
+ return true;
23037
+ }
23038
+ }
23039
+ return false;
23040
+ }
23041
+ function parseProfileName(value, label) {
23042
+ const candidate = parseNonEmptyString9(value);
23043
+ if (candidate.length === 0) {
23044
+ throw createCliError7(
23045
+ "CLI_PAIR_PROFILE_INVALID",
23046
+ `${label} is required for pairing`
23047
+ );
23048
+ }
23049
+ if (candidate.length > MAX_PROFILE_NAME_LENGTH) {
23050
+ throw createCliError7(
23051
+ "CLI_PAIR_PROFILE_INVALID",
23052
+ `${label} must be at most ${MAX_PROFILE_NAME_LENGTH} characters`
23053
+ );
23054
+ }
23055
+ if (hasControlChars2(candidate)) {
23056
+ throw createCliError7(
23057
+ "CLI_PAIR_PROFILE_INVALID",
23058
+ `${label} contains control characters`
23059
+ );
23060
+ }
23061
+ return candidate;
23062
+ }
23063
+ function parsePeerProfile(payload) {
23064
+ if (!isRecord9(payload)) {
23065
+ throw createCliError7(
23066
+ "CLI_PAIR_PROFILE_INVALID",
23067
+ "Pair profile must be an object"
23068
+ );
23069
+ }
23070
+ return {
23071
+ agentName: parseProfileName(payload.agentName, "agentName"),
23072
+ humanName: parseProfileName(payload.humanName, "humanName")
23073
+ };
23074
+ }
22918
23075
  function parsePairingTicket(value) {
22919
23076
  const ticket = parseNonEmptyString9(value);
22920
23077
  if (!ticket.startsWith(PAIRING_TICKET_PREFIX)) {
@@ -23079,10 +23236,19 @@ function parsePeerEntry(value) {
23079
23236
  "Peer entry is invalid"
23080
23237
  );
23081
23238
  }
23082
- return {
23239
+ const agentNameRaw = parseNonEmptyString9(value.agentName);
23240
+ const humanNameRaw = parseNonEmptyString9(value.humanName);
23241
+ const entry = {
23083
23242
  did,
23084
23243
  proxyUrl
23085
23244
  };
23245
+ if (agentNameRaw.length > 0) {
23246
+ entry.agentName = parseProfileName(agentNameRaw, "agentName");
23247
+ }
23248
+ if (humanNameRaw.length > 0) {
23249
+ entry.humanName = parseProfileName(humanNameRaw, "humanName");
23250
+ }
23251
+ return entry;
23086
23252
  }
23087
23253
  async function loadPeersConfig2(input) {
23088
23254
  const peersPath = resolvePeersConfigPath(input.getConfigDirImpl);
@@ -23165,6 +23331,19 @@ function parsePositiveIntegerOption(input) {
23165
23331
  }
23166
23332
  return parsed;
23167
23333
  }
23334
+ function resolveLocalPairProfile(input) {
23335
+ const humanName = parseNonEmptyString9(input.config.humanName);
23336
+ if (humanName.length === 0) {
23337
+ throw createCliError7(
23338
+ "CLI_PAIR_HUMAN_NAME_MISSING",
23339
+ "Human name is missing. Run `clawdentity invite redeem <clw_inv_...> --display-name <name>` or `clawdentity config set humanName <name>`."
23340
+ );
23341
+ }
23342
+ return {
23343
+ agentName: parseProfileName(input.agentName, "agentName"),
23344
+ humanName: parseProfileName(humanName, "humanName")
23345
+ };
23346
+ }
23168
23347
  function parseProxyUrl2(candidate) {
23169
23348
  try {
23170
23349
  const parsed = new URL(candidate);
@@ -23315,15 +23494,25 @@ function parsePairStartResponse(payload) {
23315
23494
  const ticket = parsePairingTicket(payload.ticket);
23316
23495
  const initiatorAgentDid = parseNonEmptyString9(payload.initiatorAgentDid);
23317
23496
  const expiresAt = parseNonEmptyString9(payload.expiresAt);
23497
+ let initiatorProfile;
23318
23498
  if (initiatorAgentDid.length === 0 || expiresAt.length === 0) {
23319
23499
  throw createCliError7(
23320
23500
  "CLI_PAIR_START_INVALID_RESPONSE",
23321
23501
  "Pair start response is invalid"
23322
23502
  );
23323
23503
  }
23504
+ try {
23505
+ initiatorProfile = parsePeerProfile(payload.initiatorProfile);
23506
+ } catch {
23507
+ throw createCliError7(
23508
+ "CLI_PAIR_START_INVALID_RESPONSE",
23509
+ "Pair start response is invalid"
23510
+ );
23511
+ }
23324
23512
  return {
23325
23513
  ticket,
23326
23514
  initiatorAgentDid,
23515
+ initiatorProfile,
23327
23516
  expiresAt
23328
23517
  };
23329
23518
  }
@@ -23337,16 +23526,29 @@ function parsePairConfirmResponse(payload) {
23337
23526
  const paired = payload.paired === true;
23338
23527
  const initiatorAgentDid = parseNonEmptyString9(payload.initiatorAgentDid);
23339
23528
  const responderAgentDid = parseNonEmptyString9(payload.responderAgentDid);
23529
+ let initiatorProfile;
23530
+ let responderProfile;
23340
23531
  if (!paired || initiatorAgentDid.length === 0 || responderAgentDid.length === 0) {
23341
23532
  throw createCliError7(
23342
23533
  "CLI_PAIR_CONFIRM_INVALID_RESPONSE",
23343
23534
  "Pair confirm response is invalid"
23344
23535
  );
23345
23536
  }
23537
+ try {
23538
+ initiatorProfile = parsePeerProfile(payload.initiatorProfile);
23539
+ responderProfile = parsePeerProfile(payload.responderProfile);
23540
+ } catch {
23541
+ throw createCliError7(
23542
+ "CLI_PAIR_CONFIRM_INVALID_RESPONSE",
23543
+ "Pair confirm response is invalid"
23544
+ );
23545
+ }
23346
23546
  return {
23347
23547
  paired,
23348
23548
  initiatorAgentDid,
23349
- responderAgentDid
23549
+ responderAgentDid,
23550
+ initiatorProfile,
23551
+ responderProfile
23350
23552
  };
23351
23553
  }
23352
23554
  function parsePairStatusResponse(payload) {
@@ -23367,6 +23569,7 @@ function parsePairStatusResponse(payload) {
23367
23569
  const responderAgentDid = parseNonEmptyString9(payload.responderAgentDid);
23368
23570
  const expiresAt = parseNonEmptyString9(payload.expiresAt);
23369
23571
  const confirmedAt = parseNonEmptyString9(payload.confirmedAt);
23572
+ let initiatorProfile;
23370
23573
  if (initiatorAgentDid.length === 0 || expiresAt.length === 0) {
23371
23574
  throw createCliError7(
23372
23575
  "CLI_PAIR_STATUS_INVALID_RESPONSE",
@@ -23379,16 +23582,43 @@ function parsePairStatusResponse(payload) {
23379
23582
  "Pair status response is invalid"
23380
23583
  );
23381
23584
  }
23585
+ try {
23586
+ initiatorProfile = parsePeerProfile(payload.initiatorProfile);
23587
+ } catch {
23588
+ throw createCliError7(
23589
+ "CLI_PAIR_STATUS_INVALID_RESPONSE",
23590
+ "Pair status response is invalid"
23591
+ );
23592
+ }
23593
+ let responderProfile;
23594
+ if (payload.responderProfile !== void 0) {
23595
+ try {
23596
+ responderProfile = parsePeerProfile(payload.responderProfile);
23597
+ } catch {
23598
+ throw createCliError7(
23599
+ "CLI_PAIR_STATUS_INVALID_RESPONSE",
23600
+ "Pair status response is invalid"
23601
+ );
23602
+ }
23603
+ }
23604
+ if (statusRaw === "confirmed" && responderProfile === void 0) {
23605
+ throw createCliError7(
23606
+ "CLI_PAIR_STATUS_INVALID_RESPONSE",
23607
+ "Pair status response is invalid"
23608
+ );
23609
+ }
23382
23610
  return {
23383
23611
  status: statusRaw,
23384
23612
  initiatorAgentDid,
23613
+ initiatorProfile,
23385
23614
  responderAgentDid: responderAgentDid.length > 0 ? responderAgentDid : void 0,
23615
+ responderProfile,
23386
23616
  expiresAt,
23387
23617
  confirmedAt: confirmedAt.length > 0 ? confirmedAt : void 0
23388
23618
  };
23389
23619
  }
23390
23620
  async function readAgentProofMaterial(agentName, dependencies) {
23391
- const readFileImpl = dependencies.readFileImpl ?? readFile5;
23621
+ const readFileImpl = dependencies.readFileImpl ?? readFile6;
23392
23622
  const getConfigDirImpl = dependencies.getConfigDirImpl ?? getConfigDir;
23393
23623
  const normalizedAgentName = assertValidAgentName(agentName);
23394
23624
  const agentDir = join7(
@@ -23571,7 +23801,7 @@ function resolveConfirmTicketSource(options) {
23571
23801
  }
23572
23802
  async function persistPairedPeer(input) {
23573
23803
  const getConfigDirImpl = input.dependencies.getConfigDirImpl ?? getConfigDir;
23574
- const readFileImpl = input.dependencies.readFileImpl ?? readFile5;
23804
+ const readFileImpl = input.dependencies.readFileImpl ?? readFile6;
23575
23805
  const mkdirImpl = input.dependencies.mkdirImpl ?? mkdir6;
23576
23806
  const writeFileImpl = input.dependencies.writeFileImpl ?? writeFile6;
23577
23807
  const chmodImpl = input.dependencies.chmodImpl ?? chmod4;
@@ -23587,7 +23817,9 @@ async function persistPairedPeer(input) {
23587
23817
  });
23588
23818
  peersConfig.peers[alias] = {
23589
23819
  did: input.peerDid,
23590
- proxyUrl: peerProxyUrl
23820
+ proxyUrl: peerProxyUrl,
23821
+ agentName: input.peerProfile.agentName,
23822
+ humanName: input.peerProfile.humanName
23591
23823
  };
23592
23824
  await savePeersConfig2({
23593
23825
  config: peersConfig,
@@ -23609,13 +23841,19 @@ async function startPairing(agentName, options, dependencies = {}) {
23609
23841
  config: config2,
23610
23842
  fetchImpl
23611
23843
  });
23844
+ const normalizedAgentName = assertValidAgentName(agentName);
23845
+ const initiatorProfile = resolveLocalPairProfile({
23846
+ config: config2,
23847
+ agentName: normalizedAgentName
23848
+ });
23612
23849
  const { ait, secretKey } = await readAgentProofMaterial(
23613
- agentName,
23850
+ normalizedAgentName,
23614
23851
  dependencies
23615
23852
  );
23616
23853
  const requestUrl = toProxyRequestUrl(proxyUrl, PAIR_START_PATH);
23617
23854
  const requestBody = JSON.stringify({
23618
- ttlSeconds
23855
+ ttlSeconds,
23856
+ initiatorProfile
23619
23857
  });
23620
23858
  const bodyBytes = new TextEncoder().encode(requestBody);
23621
23859
  const timestampSeconds = nowSecondsImpl();
@@ -23669,9 +23907,14 @@ async function confirmPairing(agentName, options, dependencies = {}) {
23669
23907
  const resolveConfigImpl = dependencies.resolveConfigImpl ?? resolveConfig;
23670
23908
  const nowSecondsImpl = dependencies.nowSecondsImpl ?? (() => Math.floor(Date.now() / 1e3));
23671
23909
  const nonceFactoryImpl = dependencies.nonceFactoryImpl ?? (() => randomBytes4(NONCE_SIZE2).toString("base64url"));
23672
- const readFileImpl = dependencies.readFileImpl ?? readFile5;
23910
+ const readFileImpl = dependencies.readFileImpl ?? readFile6;
23673
23911
  const qrDecodeImpl = dependencies.qrDecodeImpl ?? decodeTicketFromPng;
23674
23912
  const config2 = await resolveConfigImpl();
23913
+ const normalizedAgentName = assertValidAgentName(agentName);
23914
+ const responderProfile = resolveLocalPairProfile({
23915
+ config: config2,
23916
+ agentName: normalizedAgentName
23917
+ });
23675
23918
  const ticketSource = resolveConfirmTicketSource(options);
23676
23919
  const proxyUrl = await resolveProxyUrl({
23677
23920
  config: config2,
@@ -23701,11 +23944,14 @@ async function confirmPairing(agentName, options, dependencies = {}) {
23701
23944
  ticket = parsePairingTicket(qrDecodeImpl(new Uint8Array(imageBytes)));
23702
23945
  }
23703
23946
  const { ait, secretKey } = await readAgentProofMaterial(
23704
- agentName,
23947
+ normalizedAgentName,
23705
23948
  dependencies
23706
23949
  );
23707
23950
  const requestUrl = toProxyRequestUrl(proxyUrl, PAIR_CONFIRM_PATH);
23708
- const requestBody = JSON.stringify({ ticket });
23951
+ const requestBody = JSON.stringify({
23952
+ ticket,
23953
+ responderProfile
23954
+ });
23709
23955
  const bodyBytes = new TextEncoder().encode(requestBody);
23710
23956
  const timestampSeconds = nowSecondsImpl();
23711
23957
  const nonce = nonceFactoryImpl();
@@ -23741,6 +23987,7 @@ async function confirmPairing(agentName, options, dependencies = {}) {
23741
23987
  const peerAlias = await persistPairedPeer({
23742
23988
  ticket,
23743
23989
  peerDid: parsed.initiatorAgentDid,
23990
+ peerProfile: parsed.initiatorProfile,
23744
23991
  dependencies
23745
23992
  });
23746
23993
  if (ticketSource.source === "qr-file" && ticketSource.qrFilePath) {
@@ -23822,15 +24069,23 @@ async function getPairingStatusOnce(agentName, options, dependencies = {}) {
23822
24069
  );
23823
24070
  }
23824
24071
  const peerDid = callerAgentDid === parsed.initiatorAgentDid ? responderAgentDid : callerAgentDid === responderAgentDid ? parsed.initiatorAgentDid : void 0;
24072
+ const peerProfile = callerAgentDid === parsed.initiatorAgentDid ? parsed.responderProfile : callerAgentDid === responderAgentDid ? parsed.initiatorProfile : void 0;
23825
24073
  if (!peerDid) {
23826
24074
  throw createCliError7(
23827
24075
  "CLI_PAIR_STATUS_FORBIDDEN",
23828
24076
  "Local agent is not a participant in the pairing ticket"
23829
24077
  );
23830
24078
  }
24079
+ if (!peerProfile) {
24080
+ throw createCliError7(
24081
+ "CLI_PAIR_STATUS_INVALID_RESPONSE",
24082
+ "Pair status response is invalid"
24083
+ );
24084
+ }
23831
24085
  peerAlias = await persistPairedPeer({
23832
24086
  ticket,
23833
24087
  peerDid,
24088
+ peerProfile,
23834
24089
  dependencies
23835
24090
  });
23836
24091
  }
@@ -23926,6 +24181,12 @@ var createPairCommand = (dependencies = {}) => {
23926
24181
  writeStdoutLine("Pairing ticket created");
23927
24182
  writeStdoutLine(`Ticket: ${result.ticket}`);
23928
24183
  writeStdoutLine(`Initiator Agent DID: ${result.initiatorAgentDid}`);
24184
+ writeStdoutLine(
24185
+ `Initiator Agent Name: ${result.initiatorProfile.agentName}`
24186
+ );
24187
+ writeStdoutLine(
24188
+ `Initiator Human Name: ${result.initiatorProfile.humanName}`
24189
+ );
23929
24190
  writeStdoutLine(`Expires At: ${result.expiresAt}`);
23930
24191
  if (result.qrPath) {
23931
24192
  writeStdoutLine(`QR File: ${result.qrPath}`);
@@ -23968,6 +24229,14 @@ var createPairCommand = (dependencies = {}) => {
23968
24229
  `Responder Agent DID: ${status.responderAgentDid}`
23969
24230
  );
23970
24231
  }
24232
+ if (status.responderProfile) {
24233
+ writeStdoutLine(
24234
+ `Responder Agent Name: ${status.responderProfile.agentName}`
24235
+ );
24236
+ writeStdoutLine(
24237
+ `Responder Human Name: ${status.responderProfile.humanName}`
24238
+ );
24239
+ }
23971
24240
  if (status.peerAlias) {
23972
24241
  writeStdoutLine(`Peer alias saved: ${status.peerAlias}`);
23973
24242
  }
@@ -23988,7 +24257,19 @@ var createPairCommand = (dependencies = {}) => {
23988
24257
  });
23989
24258
  writeStdoutLine("Pairing confirmed");
23990
24259
  writeStdoutLine(`Initiator Agent DID: ${result.initiatorAgentDid}`);
24260
+ writeStdoutLine(
24261
+ `Initiator Agent Name: ${result.initiatorProfile.agentName}`
24262
+ );
24263
+ writeStdoutLine(
24264
+ `Initiator Human Name: ${result.initiatorProfile.humanName}`
24265
+ );
23991
24266
  writeStdoutLine(`Responder Agent DID: ${result.responderAgentDid}`);
24267
+ writeStdoutLine(
24268
+ `Responder Agent Name: ${result.responderProfile.agentName}`
24269
+ );
24270
+ writeStdoutLine(
24271
+ `Responder Human Name: ${result.responderProfile.humanName}`
24272
+ );
23992
24273
  writeStdoutLine(`Paired: ${result.paired ? "true" : "false"}`);
23993
24274
  if (result.peerAlias) {
23994
24275
  writeStdoutLine(`Peer alias saved: ${result.peerAlias}`);
@@ -24020,9 +24301,23 @@ var createPairCommand = (dependencies = {}) => {
24020
24301
  });
24021
24302
  writeStdoutLine(`Status: ${result.status}`);
24022
24303
  writeStdoutLine(`Initiator Agent DID: ${result.initiatorAgentDid}`);
24304
+ writeStdoutLine(
24305
+ `Initiator Agent Name: ${result.initiatorProfile.agentName}`
24306
+ );
24307
+ writeStdoutLine(
24308
+ `Initiator Human Name: ${result.initiatorProfile.humanName}`
24309
+ );
24023
24310
  if (result.responderAgentDid) {
24024
24311
  writeStdoutLine(`Responder Agent DID: ${result.responderAgentDid}`);
24025
24312
  }
24313
+ if (result.responderProfile) {
24314
+ writeStdoutLine(
24315
+ `Responder Agent Name: ${result.responderProfile.agentName}`
24316
+ );
24317
+ writeStdoutLine(
24318
+ `Responder Human Name: ${result.responderProfile.humanName}`
24319
+ );
24320
+ }
24026
24321
  writeStdoutLine(`Expires At: ${result.expiresAt}`);
24027
24322
  if (result.confirmedAt) {
24028
24323
  writeStdoutLine(`Confirmed At: ${result.confirmedAt}`);
@@ -24041,7 +24336,7 @@ import { Command as Command9 } from "commander";
24041
24336
 
24042
24337
  // src/install-skill-mode.ts
24043
24338
  import { constants, existsSync as existsSync2 } from "fs";
24044
- import { access as access3, copyFile as copyFile2, mkdir as mkdir7, readdir as readdir2, readFile as readFile6 } from "fs/promises";
24339
+ import { access as access3, copyFile as copyFile2, mkdir as mkdir7, readdir as readdir2, readFile as readFile7 } from "fs/promises";
24045
24340
  import { createRequire } from "module";
24046
24341
  import { homedir as homedir4 } from "os";
24047
24342
  import { dirname as dirname6, join as join8, relative } from "path";
@@ -24230,10 +24525,10 @@ async function resolveArtifacts(input) {
24230
24525
  );
24231
24526
  }
24232
24527
  async function copyArtifact(input) {
24233
- const sourceContent = await readFile6(input.sourcePath);
24528
+ const sourceContent = await readFile7(input.sourcePath);
24234
24529
  let existingContent;
24235
24530
  try {
24236
- existingContent = await readFile6(input.targetPath);
24531
+ existingContent = await readFile7(input.targetPath);
24237
24532
  } catch (error48) {
24238
24533
  if (getErrorCode3(error48) !== "ENOENT") {
24239
24534
  throw error48;
@@ -24365,7 +24660,7 @@ var createSkillCommand = () => {
24365
24660
  };
24366
24661
 
24367
24662
  // src/commands/verify.ts
24368
- import { readFile as readFile7 } from "fs/promises";
24663
+ import { readFile as readFile8 } from "fs/promises";
24369
24664
  import { Command as Command10 } from "commander";
24370
24665
  var logger10 = createLogger({ service: "cli", module: "verify" });
24371
24666
  var REGISTRY_KEYS_CACHE_FILE = "registry-keys.json";
@@ -24414,7 +24709,7 @@ var resolveToken = async (tokenOrFile) => {
24414
24709
  throw new VerifyCommandError("invalid token (value is empty)");
24415
24710
  }
24416
24711
  try {
24417
- const fileContents = await readFile7(input, "utf-8");
24712
+ const fileContents = await readFile8(input, "utf-8");
24418
24713
  const token = fileContents.trim();
24419
24714
  if (token.length === 0) {
24420
24715
  throw new VerifyCommandError(`invalid token (${input} is empty)`);