@hermespilot/link 0.7.2 → 0.7.3

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.
@@ -1316,10 +1316,10 @@ async function applyOwner(filePath, metadata) {
1316
1316
  }
1317
1317
  try {
1318
1318
  await chown(filePath, metadata.uid, metadata.gid);
1319
- } catch (error) {
1319
+ } catch {
1320
1320
  const current = await stat(filePath);
1321
- if (current.uid !== metadata.uid || current.gid !== metadata.gid) {
1322
- throw error;
1321
+ if (current.uid === metadata.uid && current.gid === metadata.gid) {
1322
+ return;
1323
1323
  }
1324
1324
  }
1325
1325
  }
@@ -5621,7 +5621,7 @@ function isConversationMissingError(error) {
5621
5621
  }
5622
5622
 
5623
5623
  // src/constants.ts
5624
- var LINK_VERSION = "0.7.2";
5624
+ var LINK_VERSION = "0.7.3";
5625
5625
  var LINK_COMMAND = "hermeslink";
5626
5626
  var LINK_DEFAULT_PORT = 52379;
5627
5627
  var LINK_RUNTIME_DIR_NAME = ".hermeslink";
@@ -13208,6 +13208,7 @@ async function syncHermesSessionsIntoConversations(paths, logger, options = {})
13208
13208
  reprojected_count: 0,
13209
13209
  skipped_existing: 0,
13210
13210
  skipped_hidden: 0,
13211
+ skipped_empty_transcript: 0,
13211
13212
  skipped_deleted: 0,
13212
13213
  skipped_over_limit: 0,
13213
13214
  errors: []
@@ -13279,11 +13280,28 @@ async function syncHermesSessionsIntoConversations(paths, logger, options = {})
13279
13280
  result.skipped_existing += 1;
13280
13281
  continue;
13281
13282
  }
13283
+ const candidateMessages = await readHermesLineageMessages(candidate).catch(
13284
+ (error) => {
13285
+ result.errors.push({
13286
+ profile: candidate.profileName,
13287
+ message: error instanceof Error ? error.message : String(error)
13288
+ });
13289
+ return null;
13290
+ }
13291
+ );
13292
+ if (!candidateMessages) {
13293
+ continue;
13294
+ }
13295
+ if (candidateMessages.length === 0) {
13296
+ result.skipped_empty_transcript += 1;
13297
+ continue;
13298
+ }
13282
13299
  const importedConversationId = await importHermesSession({
13283
13300
  paths,
13284
13301
  store,
13285
13302
  logger,
13286
- candidate
13303
+ candidate,
13304
+ messages: candidateMessages
13287
13305
  }).catch((error) => {
13288
13306
  result.errors.push({
13289
13307
  profile: candidate.profileName,
@@ -13387,7 +13405,10 @@ async function importHermesSession(input) {
13387
13405
  );
13388
13406
  const sessionId = candidate.session.id;
13389
13407
  const hermesSessionIds = lineageSessionIds(candidate);
13390
- const messages2 = await readHermesLineageMessages(candidate);
13408
+ const messages2 = input.messages ?? await readHermesLineageMessages(candidate);
13409
+ if (messages2.length === 0) {
13410
+ return null;
13411
+ }
13391
13412
  const now = (/* @__PURE__ */ new Date()).toISOString();
13392
13413
  const createdAt = isoFromHermesTime(candidate.session.started_at) ?? now;
13393
13414
  const updatedAt = isoFromHermesTime(candidate.session.last_active) ?? isoFromHermesTime(messages2.at(-1)?.timestamp) ?? createdAt;
@@ -13487,6 +13508,18 @@ async function mergeExistingHermesConversation(input) {
13487
13508
  }
13488
13509
  let changed = false;
13489
13510
  const candidateMessages = await readHermesLineageMessages(input.candidate);
13511
+ if (candidateMessages.length === 0 && isEmptyHermesImportPlaceholder(canonical)) {
13512
+ await softDeleteEmptyHermesImportPlaceholder({
13513
+ paths: input.paths,
13514
+ store: input.store,
13515
+ conversation: canonical,
13516
+ candidate: input.candidate
13517
+ });
13518
+ return true;
13519
+ }
13520
+ if (candidateMessages.length === 0) {
13521
+ return false;
13522
+ }
13490
13523
  const nextCanonical = await mergeHermesCandidateIntoConversation({
13491
13524
  ...input,
13492
13525
  existing: canonical,
@@ -13698,7 +13731,26 @@ function isSafeHermesImportConversation(item) {
13698
13731
  }
13699
13732
  return snapshot.messages.length === 0 || snapshot.messages.every((message) => isHermesImportedMessage(message));
13700
13733
  }
13734
+ function isEmptyHermesImportPlaceholder(item) {
13735
+ return item.manifest.status === "active" && item.snapshot.messages.length === 0 && item.snapshot.runs.length === 0 && item.manifest.title_source === "default" && isDefaultConversationTitle(item.manifest.title) && item.manifest.hermes_session_id !== void 0 && !item.manifest.hermes_session_id.startsWith("hp_");
13736
+ }
13737
+ async function softDeleteEmptyHermesImportPlaceholder(input) {
13738
+ await softDeleteHermesImportConversation({
13739
+ paths: input.paths,
13740
+ store: input.store,
13741
+ conversation: input.conversation,
13742
+ candidate: input.candidate
13743
+ });
13744
+ }
13701
13745
  async function softDeleteMergedHermesDuplicate(input) {
13746
+ await softDeleteHermesImportConversation({
13747
+ paths: input.paths,
13748
+ store: input.store,
13749
+ conversation: input.duplicate,
13750
+ candidate: input.candidate
13751
+ });
13752
+ }
13753
+ async function softDeleteHermesImportConversation(input) {
13702
13754
  const deletedAt = (/* @__PURE__ */ new Date()).toISOString();
13703
13755
  const emptySnapshot3 = {
13704
13756
  schema_version: 1,
@@ -13706,13 +13758,13 @@ async function softDeleteMergedHermesDuplicate(input) {
13706
13758
  runs: []
13707
13759
  };
13708
13760
  const hermesSessionIds = normalizeSessionIds([
13709
- input.duplicate.manifest.hermes_session_id,
13710
- ...input.duplicate.manifest.hermes_session_ids ?? [],
13711
- ...input.duplicate.manifest.hermes_lineage?.session_ids ?? [],
13761
+ input.conversation.manifest.hermes_session_id,
13762
+ ...input.conversation.manifest.hermes_session_ids ?? [],
13763
+ ...input.conversation.manifest.hermes_lineage?.session_ids ?? [],
13712
13764
  ...lineageSessionIds(input.candidate)
13713
13765
  ]);
13714
13766
  const nextManifest = {
13715
- ...input.duplicate.manifest,
13767
+ ...input.conversation.manifest,
13716
13768
  status: "deleted_soft",
13717
13769
  hermes_session_ids: hermesSessionIds,
13718
13770
  ...lineageManifestPatch(input.candidate),
@@ -13720,12 +13772,12 @@ async function softDeleteMergedHermesDuplicate(input) {
13720
13772
  deleted_at: deletedAt
13721
13773
  };
13722
13774
  const stats = buildConversationStats(
13723
- { ...nextManifest, stats: input.duplicate.manifest.stats },
13775
+ { ...nextManifest, stats: input.conversation.manifest.stats },
13724
13776
  emptySnapshot3
13725
13777
  );
13726
13778
  const tombstone = { ...nextManifest, stats };
13727
13779
  await input.store.writeManifest(tombstone);
13728
- await input.store.writeSnapshot(input.duplicate.conversationId, emptySnapshot3);
13780
+ await input.store.writeSnapshot(input.conversation.conversationId, emptySnapshot3);
13729
13781
  await upsertConversationStats(input.paths, toStatsIndexRecord(tombstone, stats));
13730
13782
  }
13731
13783
  function mergeHermesLineageIntoManifest(input) {
package/dist/cli/index.js CHANGED
@@ -53,7 +53,7 @@ import {
53
53
  stopDaemonProcess,
54
54
  summarizeUsageProbeEnsure,
55
55
  translate
56
- } from "../chunk-YPY6JEZN.js";
56
+ } from "../chunk-36L5JCHO.js";
57
57
 
58
58
  // src/cli/index.ts
59
59
  import { Command } from "commander";
@@ -409,6 +409,7 @@ interface HermesSessionSyncResult {
409
409
  reprojected_count: number;
410
410
  skipped_existing: number;
411
411
  skipped_hidden: number;
412
+ skipped_empty_transcript: number;
412
413
  skipped_deleted: number;
413
414
  skipped_over_limit: number;
414
415
  errors: Array<{
package/dist/http/app.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createApp
3
- } from "../chunk-YPY6JEZN.js";
3
+ } from "../chunk-36L5JCHO.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.7.2",
3
+ "version": "0.7.3",
4
4
  "private": false,
5
5
  "description": "Hermes Link companion service and CLI for connecting hermes-agent through HermesPilot",
6
6
  "license": "MIT",