@hermespilot/link 0.6.7 → 0.6.8

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.
@@ -1359,6 +1359,7 @@ function isNodeError(error, code) {
1359
1359
  }
1360
1360
 
1361
1361
  // src/storage/atomic-json.ts
1362
+ var jsonUpdateQueues = /* @__PURE__ */ new Map();
1362
1363
  async function readJsonFile(filePath) {
1363
1364
  try {
1364
1365
  const raw = await readFile(filePath, "utf8");
@@ -1375,6 +1376,24 @@ async function writeJsonFile(filePath, value, mode = 384) {
1375
1376
  `;
1376
1377
  await atomicWriteFilePreservingMetadata(filePath, payload, { mode });
1377
1378
  }
1379
+ async function updateJsonFile(filePath, update, mode = 384) {
1380
+ const previous = jsonUpdateQueues.get(filePath) ?? Promise.resolve();
1381
+ let next;
1382
+ const operation = previous.catch(() => void 0).then(async () => {
1383
+ const current = await readJsonFile(filePath);
1384
+ next = await update(current);
1385
+ await writeJsonFile(filePath, next, mode);
1386
+ });
1387
+ const queued = operation.catch(() => void 0);
1388
+ jsonUpdateQueues.set(filePath, queued);
1389
+ void queued.finally(() => {
1390
+ if (jsonUpdateQueues.get(filePath) === queued) {
1391
+ jsonUpdateQueues.delete(filePath);
1392
+ }
1393
+ });
1394
+ await operation;
1395
+ return next;
1396
+ }
1378
1397
  function isNodeError2(error, code) {
1379
1398
  return typeof error === "object" && error !== null && "code" in error && error.code === code;
1380
1399
  }
@@ -5485,7 +5504,7 @@ import os2 from "os";
5485
5504
  import path5 from "path";
5486
5505
 
5487
5506
  // src/constants.ts
5488
- var LINK_VERSION = "0.6.7";
5507
+ var LINK_VERSION = "0.6.8";
5489
5508
  var LINK_COMMAND = "hermeslink";
5490
5509
  var LINK_DEFAULT_PORT = 52379;
5491
5510
  var LINK_RUNTIME_DIR_NAME = ".hermeslink";
@@ -9123,6 +9142,7 @@ var ConversationMaintenanceCoordinator = class {
9123
9142
  clearPlans;
9124
9143
  archivePlans;
9125
9144
  async prepareClearAllConversationPlan(targetStatus = "active") {
9145
+ assertArchivedClearPlanTarget(targetStatus);
9126
9146
  const targets = [];
9127
9147
  for (const conversationId of await this.deps.store.listConversationIds()) {
9128
9148
  const manifest = await this.deps.store.readManifest(conversationId).catch(() => null);
@@ -9145,6 +9165,7 @@ var ConversationMaintenanceCoordinator = class {
9145
9165
  }
9146
9166
  async executeClearAllConversationPlan(planId) {
9147
9167
  let plan = await this.clearPlans.read(planId);
9168
+ assertArchivedClearPlanTarget(plan.target_status ?? "active");
9148
9169
  if (plan.status === "completed") {
9149
9170
  return plan;
9150
9171
  }
@@ -9207,6 +9228,7 @@ var ConversationMaintenanceCoordinator = class {
9207
9228
  }
9208
9229
  async startClearAllConversationPlan(planId) {
9209
9230
  const plan = await this.clearPlans.read(planId);
9231
+ assertArchivedClearPlanTarget(plan.target_status ?? "active");
9210
9232
  if (plan.status === "completed" || plan.status === "executing") {
9211
9233
  return plan;
9212
9234
  }
@@ -9688,6 +9710,16 @@ var ConversationMaintenanceCoordinator = class {
9688
9710
  return plan;
9689
9711
  }
9690
9712
  };
9713
+ function assertArchivedClearPlanTarget(targetStatus) {
9714
+ if (targetStatus === "archived") {
9715
+ return;
9716
+ }
9717
+ throw new LinkHttpError(
9718
+ 409,
9719
+ "active_conversation_clear_plan_disabled",
9720
+ "Bulk deletion of active conversations is disabled. Archive active conversations first, or delete explicitly selected conversations."
9721
+ );
9722
+ }
9691
9723
  function isVoiceAttachmentInput(attachment) {
9692
9724
  return attachment.kind === "voice" || attachment.type === "voice" || attachment.is_voice_note === true || attachment.isVoiceNote === true;
9693
9725
  }
@@ -19979,7 +20011,7 @@ function isExpectedClientDisconnectError(error) {
19979
20011
 
19980
20012
  // src/http/routes/conversations.ts
19981
20013
  function registerConversationRoutes(router, options) {
19982
- const { paths, conversations } = options;
20014
+ const { paths, logger, conversations } = options;
19983
20015
  router.get("/api/v1/conversations", async (ctx) => {
19984
20016
  await authenticateRequest(ctx, paths);
19985
20017
  ctx.set("cache-control", "no-store");
@@ -20185,12 +20217,20 @@ function registerConversationRoutes(router, options) {
20185
20217
  ctx.body = { ok: true };
20186
20218
  });
20187
20219
  router.post("/api/v1/conversations/clear-plans", async (ctx) => {
20188
- await authenticateRequest(ctx, paths);
20220
+ const auth = await authenticateRequest(ctx, paths);
20189
20221
  const body = await readJsonBody(ctx.req);
20190
20222
  const targetStatus = readConversationClearPlanTargetStatus(body);
20191
20223
  const plan = await conversations.prepareClearAllConversationPlan(
20192
20224
  targetStatus
20193
20225
  );
20226
+ void logger.warn(
20227
+ "conversation_clear_plan_prepared",
20228
+ conversationMutationAuditFields(ctx, auth, {
20229
+ plan_id: plan.id,
20230
+ target_status: plan.target_status,
20231
+ total_count: plan.total_count
20232
+ })
20233
+ );
20194
20234
  ctx.status = 201;
20195
20235
  ctx.body = {
20196
20236
  ok: true,
@@ -20208,10 +20248,19 @@ function registerConversationRoutes(router, options) {
20208
20248
  router.post(
20209
20249
  "/api/v1/conversations/clear-plans/:planId/execute",
20210
20250
  async (ctx) => {
20211
- await authenticateRequest(ctx, paths);
20251
+ const auth = await authenticateRequest(ctx, paths);
20212
20252
  const plan = await conversations.startClearAllConversationPlan(
20213
20253
  ctx.params.planId
20214
20254
  );
20255
+ void logger.warn(
20256
+ "conversation_clear_plan_execute_requested",
20257
+ conversationMutationAuditFields(ctx, auth, {
20258
+ plan_id: plan.id,
20259
+ target_status: plan.target_status,
20260
+ total_count: plan.total_count,
20261
+ status: plan.status
20262
+ })
20263
+ );
20215
20264
  ctx.status = plan.status === "completed" ? 200 : 202;
20216
20265
  ctx.body = {
20217
20266
  ok: true,
@@ -20260,7 +20309,7 @@ function registerConversationRoutes(router, options) {
20260
20309
  }
20261
20310
  );
20262
20311
  router.delete("/api/v1/conversations", async (ctx) => {
20263
- await authenticateRequest(ctx, paths);
20312
+ const auth = await authenticateRequest(ctx, paths);
20264
20313
  const body = await readJsonBody(ctx.req);
20265
20314
  const conversationIds = readStringArray(
20266
20315
  body,
@@ -20275,6 +20324,14 @@ function registerConversationRoutes(router, options) {
20275
20324
  );
20276
20325
  }
20277
20326
  const deleted = await conversations.deleteConversations(conversationIds);
20327
+ void logger.warn(
20328
+ "conversation_bulk_delete_requested",
20329
+ conversationMutationAuditFields(ctx, auth, {
20330
+ requested_count: conversationIds.length,
20331
+ deleted_count: deleted.deleted_count,
20332
+ failed_count: deleted.failed_count
20333
+ })
20334
+ );
20278
20335
  const ok = deleted.failed_count === 0;
20279
20336
  ctx.status = ok ? 200 : 409;
20280
20337
  ctx.body = {
@@ -20354,10 +20411,21 @@ function registerConversationRoutes(router, options) {
20354
20411
  }
20355
20412
  );
20356
20413
  router.delete("/api/v1/conversations/:conversationId", async (ctx) => {
20357
- await authenticateRequest(ctx, paths);
20414
+ const auth = await authenticateRequest(ctx, paths);
20415
+ const result = await conversations.deleteConversation(
20416
+ ctx.params.conversationId
20417
+ );
20418
+ void logger.warn(
20419
+ "conversation_delete_requested",
20420
+ conversationMutationAuditFields(ctx, auth, {
20421
+ conversation_id: result.conversation_id,
20422
+ hermes_deleted: result.hermes_deleted,
20423
+ hermes_session_count: result.hermes_session_ids?.length ?? 0
20424
+ })
20425
+ );
20358
20426
  ctx.body = {
20359
20427
  ok: true,
20360
- ...await conversations.deleteConversation(ctx.params.conversationId),
20428
+ ...result,
20361
20429
  blob_gc_completed: true
20362
20430
  };
20363
20431
  });
@@ -20420,6 +20488,21 @@ function readConversationClearPlanTargetStatus(body) {
20420
20488
  "Conversation clear plan target status is invalid"
20421
20489
  );
20422
20490
  }
20491
+ function conversationMutationAuditFields(ctx, auth, fields) {
20492
+ return {
20493
+ method: ctx.method,
20494
+ path: ctx.path,
20495
+ auth_kind: auth.kind,
20496
+ device_id: auth.device?.id ?? null,
20497
+ device_label: auth.device?.label ?? null,
20498
+ device_platform: auth.device?.platform ?? null,
20499
+ device_model: auth.device?.model ?? null,
20500
+ account_id: auth.accountId ?? null,
20501
+ app_instance_id: auth.appInstanceId ?? null,
20502
+ user_agent: ctx.get("user-agent") || null,
20503
+ ...fields
20504
+ };
20505
+ }
20423
20506
  function readNonNegativeIntegerHeader(value) {
20424
20507
  const raw = Array.isArray(value) ? value[0] : value;
20425
20508
  if (!raw) {
@@ -26263,12 +26346,10 @@ function computeRelayBackoffMs(attempt, options = {}) {
26263
26346
  return exponential + Math.floor(exponential * ratio);
26264
26347
  }
26265
26348
  async function updateRelayReconnectState(paths, update) {
26266
- const state = await readLinkState(paths);
26267
- const next = {
26349
+ await updateJsonFile(paths.stateFile, (state) => ({
26268
26350
  ...state,
26269
- relayReconnect: update(normalizeRelayReconnectState(state.relayReconnect))
26270
- };
26271
- await writeJsonFile(paths.stateFile, next);
26351
+ relayReconnect: update(normalizeRelayReconnectState(state?.relayReconnect))
26352
+ }));
26272
26353
  }
26273
26354
  async function readLinkState(paths) {
26274
26355
  const state = await readJsonFile(paths.stateFile);
@@ -26375,6 +26456,9 @@ function readInteger4(value) {
26375
26456
  }
26376
26457
 
26377
26458
  // src/relay/control-client.ts
26459
+ var DEFAULT_RELAY_HANDSHAKE_TIMEOUT_MS = 2e4;
26460
+ var DEFAULT_RELAY_PING_INTERVAL_MS = 3 * 6e4;
26461
+ var DEFAULT_RELAY_PONG_TIMEOUT_MS = 3e4;
26378
26462
  function connectRelayControl(options) {
26379
26463
  const wsUrl = new URL(`${options.relayBaseUrl.replace(/\/+$/u, "")}/api/v1/relay/link/connect`);
26380
26464
  wsUrl.protocol = wsUrl.protocol === "https:" ? "wss:" : "ws:";
@@ -26383,10 +26467,15 @@ function connectRelayControl(options) {
26383
26467
  const maxReconnectAttempts = options.maxReconnectAttempts ?? Number.POSITIVE_INFINITY;
26384
26468
  const backoffBaseMs = options.backoffBaseMs ?? DEFAULT_RELAY_RECONNECT_BASE_MS;
26385
26469
  const backoffMaxMs = options.backoffMaxMs ?? DEFAULT_RELAY_RECONNECT_MAX_MS;
26470
+ const handshakeTimeoutMs = positiveInteger2(options.handshakeTimeoutMs, DEFAULT_RELAY_HANDSHAKE_TIMEOUT_MS);
26471
+ const pingIntervalMs = positiveInteger2(options.pingIntervalMs, DEFAULT_RELAY_PING_INTERVAL_MS);
26472
+ const pongTimeoutMs = positiveInteger2(options.pongTimeoutMs, DEFAULT_RELAY_PONG_TIMEOUT_MS);
26386
26473
  let reconnectAttempts = 0;
26387
26474
  let closedByUser = false;
26388
26475
  let socket = null;
26389
26476
  let retryTimer = null;
26477
+ let pingTimer = null;
26478
+ let pongTimer = null;
26390
26479
  let abortControllers = /* @__PURE__ */ new Map();
26391
26480
  let fatalRelayRejection = null;
26392
26481
  let relayRetryAfterMs = null;
@@ -26414,15 +26503,19 @@ function connectRelayControl(options) {
26414
26503
  });
26415
26504
  };
26416
26505
  const connect = () => {
26506
+ clearRetryTimer();
26507
+ clearHeartbeatTimers();
26417
26508
  options.onStatus?.({ state: "connecting", attempt: reconnectAttempts });
26418
26509
  fatalRelayRejection = null;
26419
26510
  relayRetryAfterMs = null;
26420
26511
  let closeHandled = false;
26512
+ let localCloseReason;
26421
26513
  const handleConnectionClosed = (reason) => {
26422
26514
  if (closeHandled) {
26423
26515
  return;
26424
26516
  }
26425
26517
  closeHandled = true;
26518
+ clearHeartbeatTimers();
26426
26519
  abortAll(abortControllers);
26427
26520
  abortControllers = /* @__PURE__ */ new Map();
26428
26521
  if (fatalRelayRejection) {
@@ -26449,30 +26542,48 @@ function connectRelayControl(options) {
26449
26542
  scheduleTimer(backoffMaxMs, "retrying", `Relay reconnect scheduling failed: ${message}`);
26450
26543
  });
26451
26544
  };
26452
- socket = new WebSocket(wsUrl, {
26545
+ const currentSocket = new WebSocket(wsUrl, {
26546
+ handshakeTimeout: handshakeTimeoutMs,
26453
26547
  headers: {
26454
26548
  "x-hermes-link-version": LINK_VERSION
26455
26549
  }
26456
26550
  });
26457
- socket.on("open", () => {
26551
+ socket = currentSocket;
26552
+ currentSocket.on("open", () => {
26553
+ if (socket !== currentSocket) {
26554
+ return;
26555
+ }
26458
26556
  reconnectAttempts = 0;
26459
26557
  void clearRelayReconnectState(paths).catch(() => void 0);
26460
26558
  options.onStatus?.({ state: "connected", attempt: reconnectAttempts });
26461
- const currentSocket = socket;
26462
- if (currentSocket && latestNetworkRoutes) {
26559
+ startHeartbeat(currentSocket, (message) => {
26560
+ localCloseReason = message;
26561
+ options.onStatus?.({ state: "disconnected", attempt: reconnectAttempts, message });
26562
+ currentSocket.terminate();
26563
+ });
26564
+ if (latestNetworkRoutes) {
26463
26565
  sendNetworkRoutes(currentSocket, options.linkId, latestNetworkRoutes);
26464
26566
  }
26465
26567
  });
26466
- socket.on("message", (raw) => {
26467
- if (!socket || typeof raw !== "string" && !Buffer.isBuffer(raw)) {
26568
+ currentSocket.on("pong", () => {
26569
+ if (socket !== currentSocket) {
26468
26570
  return;
26469
26571
  }
26470
- void handleFrame(socket, String(raw), options.localPort, abortControllers, streamBatchPolicy).catch((error) => {
26572
+ clearPongTimer();
26573
+ });
26574
+ currentSocket.on("message", (raw) => {
26575
+ if (socket !== currentSocket || typeof raw !== "string" && !Buffer.isBuffer(raw)) {
26576
+ return;
26577
+ }
26578
+ void handleFrame(currentSocket, String(raw), options.localPort, abortControllers, streamBatchPolicy).catch((error) => {
26471
26579
  const message = error instanceof Error ? error.message : "Relay request failed";
26472
- socket?.send(JSON.stringify({ type: "http.error", id: "unknown", status: 502, message }));
26580
+ currentSocket.send(JSON.stringify({ type: "http.error", id: "unknown", status: 502, message }));
26473
26581
  });
26474
26582
  });
26475
- socket.on("unexpected-response", (request, response) => {
26583
+ currentSocket.on("unexpected-response", (request, response) => {
26584
+ if (socket !== currentSocket) {
26585
+ return;
26586
+ }
26476
26587
  const statusCode = response.statusCode ?? 0;
26477
26588
  fatalRelayRejection = resolveFatalRelayRejectionFromStatus(statusCode);
26478
26589
  relayRetryAfterMs = readRetryAfterMs(response);
@@ -26486,7 +26597,10 @@ function connectRelayControl(options) {
26486
26597
  handleConnectionClosed(message);
26487
26598
  request.destroy();
26488
26599
  });
26489
- socket.on("error", (error) => {
26600
+ currentSocket.on("error", (error) => {
26601
+ if (socket !== currentSocket) {
26602
+ return;
26603
+ }
26490
26604
  const message = error instanceof Error ? error.message : "Relay websocket error";
26491
26605
  fatalRelayRejection = resolveFatalRelayRejection(message);
26492
26606
  options.onStatus?.({
@@ -26495,8 +26609,12 @@ function connectRelayControl(options) {
26495
26609
  message: fatalRelayRejection ?? message
26496
26610
  });
26497
26611
  });
26498
- socket.on("close", () => {
26499
- handleConnectionClosed();
26612
+ currentSocket.on("close", (code, reason) => {
26613
+ if (socket !== currentSocket) {
26614
+ return;
26615
+ }
26616
+ socket = null;
26617
+ handleConnectionClosed(localCloseReason ?? formatCloseReason(code, reason));
26500
26618
  });
26501
26619
  };
26502
26620
  startConnect();
@@ -26526,10 +26644,59 @@ function connectRelayControl(options) {
26526
26644
  return await readRelayCooldownDelayMs(paths).catch(() => 0);
26527
26645
  }
26528
26646
  function scheduleTimer(delay4, state, message) {
26647
+ clearRetryTimer();
26529
26648
  options.onStatus?.({ state, attempt: reconnectAttempts, message });
26530
26649
  retryTimer = setTimeout(connect, delay4);
26531
26650
  retryTimer.unref?.();
26532
26651
  }
26652
+ function clearRetryTimer() {
26653
+ if (retryTimer == null) {
26654
+ return;
26655
+ }
26656
+ clearTimeout(retryTimer);
26657
+ retryTimer = null;
26658
+ }
26659
+ function startHeartbeat(currentSocket, onTimeout) {
26660
+ clearHeartbeatTimers();
26661
+ pingTimer = setInterval(() => {
26662
+ if (socket !== currentSocket || currentSocket.readyState !== WebSocket.OPEN) {
26663
+ clearHeartbeatTimers();
26664
+ return;
26665
+ }
26666
+ if (pongTimer != null) {
26667
+ return;
26668
+ }
26669
+ try {
26670
+ currentSocket.ping();
26671
+ } catch {
26672
+ onTimeout("Relay websocket ping failed");
26673
+ return;
26674
+ }
26675
+ pongTimer = setTimeout(() => {
26676
+ if (socket !== currentSocket || currentSocket.readyState !== WebSocket.OPEN) {
26677
+ clearPongTimer();
26678
+ return;
26679
+ }
26680
+ onTimeout(`Relay websocket pong timed out after ${pongTimeoutMs}ms`);
26681
+ }, pongTimeoutMs);
26682
+ pongTimer.unref?.();
26683
+ }, pingIntervalMs);
26684
+ pingTimer.unref?.();
26685
+ }
26686
+ function clearHeartbeatTimers() {
26687
+ if (pingTimer != null) {
26688
+ clearInterval(pingTimer);
26689
+ pingTimer = null;
26690
+ }
26691
+ clearPongTimer();
26692
+ }
26693
+ function clearPongTimer() {
26694
+ if (pongTimer == null) {
26695
+ return;
26696
+ }
26697
+ clearTimeout(pongTimer);
26698
+ pongTimer = null;
26699
+ }
26533
26700
  return {
26534
26701
  publishNetworkRoutes(routes) {
26535
26702
  latestNetworkRoutes = routes;
@@ -26543,10 +26710,8 @@ function connectRelayControl(options) {
26543
26710
  },
26544
26711
  close() {
26545
26712
  closedByUser = true;
26546
- if (retryTimer) {
26547
- clearTimeout(retryTimer);
26548
- retryTimer = null;
26549
- }
26713
+ clearRetryTimer();
26714
+ clearHeartbeatTimers();
26550
26715
  abortAll(abortControllers);
26551
26716
  socket?.terminate();
26552
26717
  }
@@ -26598,6 +26763,16 @@ function readRetryAfterMs(response) {
26598
26763
  }
26599
26764
  return Math.max(0, dateMs - Date.now());
26600
26765
  }
26766
+ function formatCloseReason(code, reason) {
26767
+ const text = reason.toString("utf8").trim();
26768
+ if (code === 1e3 && !text) {
26769
+ return void 0;
26770
+ }
26771
+ return text ? `Relay websocket closed (${code}): ${text}` : `Relay websocket closed (${code})`;
26772
+ }
26773
+ function positiveInteger2(value, fallback) {
26774
+ return Number.isFinite(value) ? Math.max(1, Math.floor(value)) : fallback;
26775
+ }
26601
26776
  async function handleFrame(socket, raw, localPort, abortControllers, streamBatchPolicy) {
26602
26777
  const frame = JSON.parse(raw);
26603
26778
  if (frame.type === "relay.config.update") {
@@ -26723,8 +26898,7 @@ async function readRelayStatusSnapshot(paths) {
26723
26898
  return normalizeRelayStatusSnapshot(state.relayStatus);
26724
26899
  }
26725
26900
  async function writeRelayStatusSnapshot(paths, status, now = /* @__PURE__ */ new Date()) {
26726
- const current = await readLinkState2(paths);
26727
- await writeJsonFile(paths.stateFile, {
26901
+ await updateLinkState(paths, (current) => ({
26728
26902
  ...current,
26729
26903
  relayStatus: {
26730
26904
  state: status.state,
@@ -26732,7 +26906,10 @@ async function writeRelayStatusSnapshot(paths, status, now = /* @__PURE__ */ new
26732
26906
  message: normalizeMessage(status.message),
26733
26907
  updatedAt: now.toISOString()
26734
26908
  }
26735
- });
26909
+ }));
26910
+ }
26911
+ async function updateLinkState(paths, update) {
26912
+ await updateJsonFile(paths.stateFile, (state) => update(state && typeof state === "object" ? state : {}));
26736
26913
  }
26737
26914
  async function readLinkState2(paths) {
26738
26915
  const state = await readJsonFile(paths.stateFile);
@@ -27151,12 +27328,10 @@ async function mergeLastReportedPublicRoutes(paths, snapshotInput) {
27151
27328
  };
27152
27329
  }
27153
27330
  async function updateNetworkReportState(paths, update) {
27154
- const state = await readLinkState3(paths);
27155
- const next = {
27331
+ await updateJsonFile(paths.stateFile, (state) => ({
27156
27332
  ...state,
27157
- networkReport: update(normalizeNetworkReportState(state.networkReport))
27158
- };
27159
- await writeJsonFile(paths.stateFile, next);
27333
+ networkReport: update(normalizeNetworkReportState(state?.networkReport))
27334
+ }));
27160
27335
  }
27161
27336
  async function readLinkState3(paths) {
27162
27337
  const state = await readJsonFile(paths.stateFile);
@@ -30817,7 +30992,7 @@ async function createApp(options = {}) {
30817
30992
  conversations,
30818
30993
  syncCronDeliveries
30819
30994
  });
30820
- registerConversationRoutes(router, { paths, conversations });
30995
+ registerConversationRoutes(router, { paths, logger, conversations });
30821
30996
  registerRunRoutes(router, { paths, logger, conversations });
30822
30997
  registerProfileRoutes(router, { paths, logger, conversations });
30823
30998
  app.use(router.routes());
package/dist/cli/index.js CHANGED
@@ -51,7 +51,7 @@ import {
51
51
  startLinkService,
52
52
  stopDaemonProcess,
53
53
  translate
54
- } from "../chunk-FWX7ZUP4.js";
54
+ } from "../chunk-57ZJLOQA.js";
55
55
 
56
56
  // src/cli/index.ts
57
57
  import { Command } from "commander";
package/dist/http/app.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createApp
3
- } from "../chunk-FWX7ZUP4.js";
3
+ } from "../chunk-57ZJLOQA.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.6.7",
3
+ "version": "0.6.8",
4
4
  "private": false,
5
5
  "description": "Hermes Link companion service and CLI for connecting hermes-agent through HermesPilot",
6
6
  "license": "MIT",