@hermespilot/link 0.2.9 → 0.3.1

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.
@@ -3724,7 +3724,7 @@ import os2 from "os";
3724
3724
  import path5 from "path";
3725
3725
 
3726
3726
  // src/constants.ts
3727
- var LINK_VERSION = "0.2.9";
3727
+ var LINK_VERSION = "0.3.1";
3728
3728
  var LINK_COMMAND = "hermeslink";
3729
3729
  var LINK_DEFAULT_PORT = 52379;
3730
3730
  var LINK_RUNTIME_DIR_NAME = ".hermeslink";
@@ -19122,35 +19122,49 @@ async function preparePairing(paths = resolveRuntimePaths()) {
19122
19122
  public_key_pem: identity.public_key_pem
19123
19123
  });
19124
19124
  const relayBaseUrl = created.relayBaseUrl || config.relayBaseUrl;
19125
- const assigned = await bootstrapRelayLink({
19126
- relayBaseUrl,
19127
- relayBootstrapToken: created.relayBootstrapToken,
19128
- identity,
19129
- paths
19130
- });
19131
- const updatedIdentity = await loadIdentity(paths) ?? identity;
19132
- const routes = await discoverRouteCandidates({
19133
- port: config.port,
19134
- relayBaseUrl,
19135
- relayBootstrapToken: created.relayBootstrapToken,
19136
- configuredLanHost: config.lanHost,
19137
- linkId: assigned.linkId,
19138
- installId: updatedIdentity.install_id,
19139
- publicKeyPem: updatedIdentity.public_key_pem
19140
- });
19141
- await patchServerJson(config.serverBaseUrl, `/api/v1/link-pairings/${created.sessionId}/link`, created.pairingToken, {
19142
- install_id: updatedIdentity.install_id,
19143
- link_id: assigned.linkId,
19144
- link_version: LINK_VERSION,
19145
- display_name: systemInfo.defaultDisplayName,
19146
- platform: systemInfo.platform,
19147
- hostname: systemInfo.hostname ?? void 0,
19148
- lan_ips: routes.lanIps,
19149
- public_ipv4s: routes.publicIpv4s,
19150
- public_ipv6s: routes.publicIpv6s,
19151
- preferred_urls: routes.preferredUrls,
19152
- environment: routes.environment
19153
- });
19125
+ let assigned;
19126
+ let updatedIdentity;
19127
+ let routes;
19128
+ try {
19129
+ assigned = await bootstrapRelayLink({
19130
+ relayBaseUrl,
19131
+ relayBootstrapToken: created.relayBootstrapToken,
19132
+ identity,
19133
+ paths
19134
+ });
19135
+ updatedIdentity = await loadIdentity(paths) ?? identity;
19136
+ routes = await discoverRouteCandidates({
19137
+ port: config.port,
19138
+ relayBaseUrl,
19139
+ relayBootstrapToken: created.relayBootstrapToken,
19140
+ configuredLanHost: config.lanHost,
19141
+ linkId: assigned.linkId,
19142
+ installId: updatedIdentity.install_id,
19143
+ publicKeyPem: updatedIdentity.public_key_pem
19144
+ });
19145
+ await patchServerJson(config.serverBaseUrl, `/api/v1/link-pairings/${created.sessionId}/link`, created.pairingToken, {
19146
+ install_id: updatedIdentity.install_id,
19147
+ link_id: assigned.linkId,
19148
+ link_version: LINK_VERSION,
19149
+ display_name: systemInfo.defaultDisplayName,
19150
+ platform: systemInfo.platform,
19151
+ hostname: systemInfo.hostname ?? void 0,
19152
+ lan_ips: routes.lanIps,
19153
+ public_ipv4s: routes.publicIpv4s,
19154
+ public_ipv6s: routes.publicIpv6s,
19155
+ preferred_urls: routes.preferredUrls,
19156
+ environment: routes.environment
19157
+ });
19158
+ } catch (error) {
19159
+ await reportPairingErrorToServer({
19160
+ serverBaseUrl: config.serverBaseUrl,
19161
+ sessionId: created.sessionId,
19162
+ source: "link",
19163
+ pairingToken: created.pairingToken,
19164
+ error: pairingErrorSnapshot("prepare_pairing", error)
19165
+ });
19166
+ throw error;
19167
+ }
19154
19168
  const qrPayload = {
19155
19169
  kind: "hermes_link_pairing",
19156
19170
  version: 1,
@@ -19241,14 +19255,26 @@ async function clearPairingClaim(sessionId, paths = resolveRuntimePaths()) {
19241
19255
  async function claimPairing(input) {
19242
19256
  const paths = input.paths ?? resolveRuntimePaths();
19243
19257
  const [identity, config] = await Promise.all([loadRequiredIdentity2(paths), loadConfig(paths)]);
19244
- const verified = await postServerJson(
19245
- config.serverBaseUrl,
19246
- `/api/v1/link-pairings/${input.sessionId}/claim/verify`,
19247
- {
19248
- claim_token: input.claimToken,
19249
- app_instance_id: input.appInstanceId ?? void 0
19250
- }
19251
- );
19258
+ let verified;
19259
+ try {
19260
+ verified = await postServerJson(
19261
+ config.serverBaseUrl,
19262
+ `/api/v1/link-pairings/${input.sessionId}/claim/verify`,
19263
+ {
19264
+ claim_token: input.claimToken,
19265
+ app_instance_id: input.appInstanceId ?? void 0
19266
+ }
19267
+ );
19268
+ } catch (error) {
19269
+ await reportPairingErrorToServer({
19270
+ serverBaseUrl: config.serverBaseUrl,
19271
+ sessionId: input.sessionId,
19272
+ source: "link",
19273
+ claimToken: input.claimToken,
19274
+ error: pairingErrorSnapshot("claim_verify", error)
19275
+ });
19276
+ throw error;
19277
+ }
19252
19278
  if (verified.ok !== true || verified.linkId !== identity.link_id) {
19253
19279
  throw new LinkHttpError(409, "pairing_claim_mismatch", "Pairing claim does not match this Link");
19254
19280
  }
@@ -19295,6 +19321,36 @@ async function postServerJson(serverBaseUrl, path24, body) {
19295
19321
  });
19296
19322
  return readJsonResponse2(response);
19297
19323
  }
19324
+ async function reportPairingErrorToServer(input) {
19325
+ const body = {
19326
+ source: input.source,
19327
+ error: input.error
19328
+ };
19329
+ if (input.claimToken) {
19330
+ body.claim_token = input.claimToken;
19331
+ }
19332
+ if (input.pairingToken) {
19333
+ body.pairing_token = input.pairingToken;
19334
+ }
19335
+ await fetch(`${input.serverBaseUrl.replace(/\/+$/u, "")}/api/v1/link-pairings/${encodeURIComponent(input.sessionId)}/error`, {
19336
+ method: "POST",
19337
+ headers: {
19338
+ accept: "application/json",
19339
+ "content-type": "application/json",
19340
+ ...input.pairingToken ? { authorization: `Bearer ${input.pairingToken}` } : {}
19341
+ },
19342
+ signal: AbortSignal.timeout(3e3),
19343
+ body: JSON.stringify(body)
19344
+ }).catch(() => void 0);
19345
+ }
19346
+ function pairingErrorSnapshot(stage, error) {
19347
+ return {
19348
+ stage,
19349
+ message: error instanceof Error ? error.message : String(error),
19350
+ error_name: error instanceof Error ? error.name : void 0,
19351
+ occurred_at: (/* @__PURE__ */ new Date()).toISOString()
19352
+ };
19353
+ }
19298
19354
  async function patchServerJson(serverBaseUrl, path24, token, body) {
19299
19355
  const response = await fetch(`${serverBaseUrl.replace(/\/+$/u, "")}${path24}`, {
19300
19356
  method: "PATCH",
package/dist/cli/index.js CHANGED
@@ -30,7 +30,7 @@ import {
30
30
  startDaemonProcess,
31
31
  startLinkService,
32
32
  stopDaemonProcess
33
- } from "../chunk-VLTX75SY.js";
33
+ } from "../chunk-PSHYSZAP.js";
34
34
 
35
35
  // src/cli/index.ts
36
36
  import { Command } from "commander";
package/dist/http/app.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createApp
3
- } from "../chunk-VLTX75SY.js";
3
+ } from "../chunk-PSHYSZAP.js";
4
4
  export {
5
5
  createApp
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hermespilot/link",
3
- "version": "0.2.9",
3
+ "version": "0.3.1",
4
4
  "private": false,
5
5
  "description": "Hermes Link companion service and CLI for connecting hermes-agent through HermesPilot",
6
6
  "license": "MIT",