@hermespilot/link 0.8.2 → 0.8.4

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.
@@ -5,7 +5,7 @@ import Router from "@koa/router";
5
5
  // src/conversations/conversation-service.ts
6
6
  import { EventEmitter } from "events";
7
7
  import { createHash as createHash9, randomUUID as randomUUID13 } from "crypto";
8
- import path27 from "path";
8
+ import path28 from "path";
9
9
 
10
10
  // src/database/link-database.ts
11
11
  import { mkdir } from "fs/promises";
@@ -7632,7 +7632,7 @@ async function listCronOutputFiles(profileName, jobId) {
7632
7632
  orderTimeMs: fileStat.mtimeMs
7633
7633
  });
7634
7634
  }
7635
- return files.sort((left, right) => left.orderTimeMs - right.orderTimeMs).map(({ path: path38, mtime }) => ({ path: path38, mtime }));
7635
+ return files.sort((left, right) => left.orderTimeMs - right.orderTimeMs).map(({ path: path39, mtime }) => ({ path: path39, mtime }));
7636
7636
  }
7637
7637
  function readCronOutputTimestamp(fileName) {
7638
7638
  const match = fileName.match(
@@ -7721,7 +7721,7 @@ function isConversationMissingError(error) {
7721
7721
  }
7722
7722
 
7723
7723
  // src/constants.ts
7724
- var LINK_VERSION = "0.8.2";
7724
+ var LINK_VERSION = "0.8.4";
7725
7725
  var LINK_COMMAND = "hermeslink";
7726
7726
  var LINK_DEFAULT_PORT = 52379;
7727
7727
  var LINK_RUNTIME_DIR_NAME = ".hermeslink";
@@ -14803,6 +14803,8 @@ function toSummary(manifest, snapshot, profile) {
14803
14803
  id: manifest.id,
14804
14804
  title: manifest.title,
14805
14805
  title_source: manifest.title_source,
14806
+ category: manifestHasCronSignal(manifest, snapshot) ? "cron" : "chat",
14807
+ is_cron: manifestHasCronSignal(manifest, snapshot),
14806
14808
  workspace_id: manifest.workspace_id ?? null,
14807
14809
  created_at: manifest.created_at,
14808
14810
  updated_at: manifest.updated_at,
@@ -14823,6 +14825,34 @@ function toSummary(manifest, snapshot, profile) {
14823
14825
  } : null
14824
14826
  };
14825
14827
  }
14828
+ function manifestHasCronSignal(manifest, snapshot) {
14829
+ const sessionIds = [
14830
+ manifest.hermes_session_id,
14831
+ ...manifest.hermes_session_ids ?? [],
14832
+ manifest.hermes_lineage?.root_session_id,
14833
+ manifest.hermes_lineage?.current_session_id,
14834
+ ...manifest.hermes_lineage?.session_ids ?? []
14835
+ ].map((value) => value?.trim()).filter((value) => Boolean(value));
14836
+ if (sessionIds.some((sessionId) => sessionId.startsWith("cron_"))) {
14837
+ return true;
14838
+ }
14839
+ if (snapshot?.messages.some((message) => {
14840
+ const raw = message.raw;
14841
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) {
14842
+ const format = raw.format;
14843
+ if (format === "hermes-link-cron-delivery") {
14844
+ return true;
14845
+ }
14846
+ }
14847
+ return Boolean(message.hermes?.cron_job_id || message.hermes?.cron_output_path);
14848
+ })) {
14849
+ return true;
14850
+ }
14851
+ return normalizeTitle(manifest.title) === "HermesLink \u5B9A\u65F6\u4EFB\u52A1";
14852
+ }
14853
+ function normalizeTitle(value) {
14854
+ return value.trim();
14855
+ }
14826
14856
  function isDefaultConversationTitle(title) {
14827
14857
  const normalized = title.trim().toLowerCase();
14828
14858
  return !normalized || normalized === "untitled" || normalized === "new chat" || normalized === DEFAULT_CONVERSATION_TITLE.toLowerCase();
@@ -19735,14 +19765,16 @@ var ConversationQueryCoordinator = class {
19735
19765
  status,
19736
19766
  limit,
19737
19767
  cursor,
19738
- workspace: options.workspace
19768
+ workspace: options.workspace,
19769
+ category: options.category
19739
19770
  }),
19740
19771
  listPage: (pageCursor) => listConversationStatsPage(this.deps.paths, {
19741
19772
  status,
19742
19773
  limit,
19743
19774
  cursor: pageCursor,
19744
19775
  workspace: options.workspace
19745
- })
19776
+ }),
19777
+ category: options.category
19746
19778
  });
19747
19779
  }
19748
19780
  async searchConversationPage(options = {}) {
@@ -19790,7 +19822,8 @@ var ConversationQueryCoordinator = class {
19790
19822
  usedIndex = true;
19791
19823
  const summaries = await this.summarizeIndexedConversations(
19792
19824
  input.status,
19793
- indexedPage.records
19825
+ indexedPage.records,
19826
+ input.category
19794
19827
  );
19795
19828
  for (const summary of summaries) {
19796
19829
  if (!seenConversationIds.add(summary.id)) {
@@ -19830,15 +19863,18 @@ var ConversationQueryCoordinator = class {
19830
19863
  }
19831
19864
  };
19832
19865
  }
19833
- async listConversationsFromStore(status = "active", workspace) {
19866
+ async listConversationsFromStore(status = "active", options = {}) {
19834
19867
  const summaries = [];
19835
19868
  for (const conversationId of await this.deps.store.listConversationIds()) {
19836
19869
  const manifest = await this.deps.store.readManifest(conversationId).catch(() => null);
19837
- if (!manifest || manifest.status !== status || !matchesWorkspaceFilter(manifest, workspace)) {
19870
+ if (!manifest || manifest.status !== status || !matchesWorkspaceFilter(manifest, options.workspace)) {
19838
19871
  continue;
19839
19872
  }
19840
19873
  const snapshot = await this.deps.store.readSnapshot(conversationId).catch(() => emptySnapshot2());
19841
19874
  const refreshed = await this.deps.metadata.refreshTitleFromHermes(manifest, { snapshot }).catch(() => manifest);
19875
+ if (!matchesConversationCategory(refreshed, snapshot, options.category)) {
19876
+ continue;
19877
+ }
19842
19878
  summaries.push(await this.summarizeConversation(refreshed, snapshot));
19843
19879
  }
19844
19880
  return summaries.sort(
@@ -19846,10 +19882,10 @@ var ConversationQueryCoordinator = class {
19846
19882
  );
19847
19883
  }
19848
19884
  async listConversationPageFromStore(input) {
19849
- const all = await this.listConversationsFromStore(
19850
- input.status,
19851
- input.workspace
19852
- );
19885
+ const all = await this.listConversationsFromStore(input.status, {
19886
+ workspace: input.workspace,
19887
+ category: input.category
19888
+ });
19853
19889
  const startIndex = input.cursor ? all.findIndex(
19854
19890
  (summary) => isAfterConversationListCursor(summary, input.cursor)
19855
19891
  ) : 0;
@@ -19868,7 +19904,7 @@ var ConversationQueryCoordinator = class {
19868
19904
  }
19869
19905
  };
19870
19906
  }
19871
- async summarizeIndexedConversations(status, records) {
19907
+ async summarizeIndexedConversations(status, records, category = "all") {
19872
19908
  const summaries = [];
19873
19909
  for (const record of records) {
19874
19910
  const manifest = await this.deps.store.readManifest(record.conversationId).catch(() => null);
@@ -19877,6 +19913,9 @@ var ConversationQueryCoordinator = class {
19877
19913
  }
19878
19914
  const snapshot = await this.deps.store.readSnapshot(record.conversationId).catch(() => emptySnapshot2());
19879
19915
  const refreshed = await this.deps.metadata.refreshTitleFromHermes(manifest, { snapshot }).catch(() => manifest);
19916
+ if (!matchesConversationCategory(refreshed, snapshot, category)) {
19917
+ continue;
19918
+ }
19880
19919
  summaries.push(await this.summarizeConversation(refreshed, snapshot));
19881
19920
  }
19882
19921
  return summaries;
@@ -20145,6 +20184,13 @@ function matchesWorkspaceFilter(manifest, filter) {
20145
20184
  }
20146
20185
  return workspaceId === filter.workspaceId;
20147
20186
  }
20187
+ function matchesConversationCategory(manifest, snapshot, category = "all") {
20188
+ if (category === "all") {
20189
+ return true;
20190
+ }
20191
+ const isCron = manifestHasCronSignal(manifest, snapshot);
20192
+ return category === "cron" ? isCron : !isCron;
20193
+ }
20148
20194
  function isAfterConversationListCursor(summary, cursor) {
20149
20195
  return summary.updated_at < cursor.updatedAt || summary.updated_at === cursor.updatedAt && summary.id < cursor.conversationId;
20150
20196
  }
@@ -21380,6 +21426,7 @@ var MESSAGE_COLUMNS = [
21380
21426
  "reasoning_details",
21381
21427
  "codex_reasoning_items"
21382
21428
  ];
21429
+ var HERMES_ROW_SESSION_POSITION = /* @__PURE__ */ Symbol("hermesRowSessionPosition");
21383
21430
  async function syncHermesSessionsIntoConversations(paths, logger, options = {}) {
21384
21431
  const maxImports = options.maxImports ?? MAX_IMPORTABLE_SESSIONS;
21385
21432
  const store = new ConversationStore(paths);
@@ -21391,6 +21438,7 @@ async function syncHermesSessionsIntoConversations(paths, logger, options = {})
21391
21438
  eligible_sessions: 0,
21392
21439
  imported_count: 0,
21393
21440
  reprojected_count: 0,
21441
+ hermes_archived_count: 0,
21394
21442
  skipped_existing: 0,
21395
21443
  skipped_hidden: 0,
21396
21444
  skipped_empty_transcript: 0,
@@ -21416,6 +21464,21 @@ async function syncHermesSessionsIntoConversations(paths, logger, options = {})
21416
21464
  continue;
21417
21465
  }
21418
21466
  if (isHiddenSession(session)) {
21467
+ if (isArchivedSession(session)) {
21468
+ const candidate = { profileName, profileDir, dbPath, session };
21469
+ result.hermes_archived_count += await archiveKnownHermesConversation({
21470
+ paths,
21471
+ store,
21472
+ knownHermesSessions,
21473
+ candidate
21474
+ }).catch((error) => {
21475
+ result.errors.push({
21476
+ profile: profileName,
21477
+ message: error instanceof Error ? error.message : String(error)
21478
+ });
21479
+ return 0;
21480
+ });
21481
+ }
21419
21482
  result.skipped_hidden += 1;
21420
21483
  continue;
21421
21484
  }
@@ -21501,7 +21564,7 @@ async function syncHermesSessionsIntoConversations(paths, logger, options = {})
21501
21564
  }
21502
21565
  }
21503
21566
  }
21504
- if (result.imported_count > 0 || result.reprojected_count > 0 || result.errors.length > 0) {
21567
+ if (result.imported_count > 0 || result.reprojected_count > 0 || result.hermes_archived_count > 0 || result.errors.length > 0) {
21505
21568
  void logger.info("hermes_session_sync_completed", { ...result });
21506
21569
  } else {
21507
21570
  void logger.debug("hermes_session_sync_completed", { ...result });
@@ -21585,7 +21648,7 @@ async function syncHermesCronSessionIntoConversations(paths, logger, input) {
21585
21648
  async function syncHermesConversationMessages(paths, logger, input) {
21586
21649
  const store = input.store ?? new ConversationStore(paths);
21587
21650
  const manifest = await store.readActiveManifest(input.conversationId);
21588
- const snapshot = await store.readSnapshot(input.conversationId);
21651
+ let snapshot = await store.readSnapshot(input.conversationId);
21589
21652
  const targets = collectHermesSessionDeleteTargets(manifest, snapshot);
21590
21653
  const result = {
21591
21654
  conversation_id: input.conversationId,
@@ -21597,8 +21660,15 @@ async function syncHermesConversationMessages(paths, logger, input) {
21597
21660
  if (targets.length === 0) {
21598
21661
  return result;
21599
21662
  }
21663
+ const duplicateCleanup = pruneStrictImportedDuplicateMessages(paths, snapshot);
21664
+ if (duplicateCleanup.removedCount > 0) {
21665
+ snapshot = duplicateCleanup.snapshot;
21666
+ result.removed_duplicate_count = duplicateCleanup.removedCount;
21667
+ result.changed = true;
21668
+ }
21600
21669
  const candidates = await collectConversationSyncCandidates(targets);
21601
21670
  const knownExactKeys = collectKnownHermesRowKeys(snapshot);
21671
+ const representedRows = collectRepresentedHermesRows(paths, snapshot);
21602
21672
  const representedMessages = collectRepresentedMessageSignatures(snapshot);
21603
21673
  const projectedMessages = [];
21604
21674
  const candidateProfiles = /* @__PURE__ */ new Map();
@@ -21608,6 +21678,12 @@ async function syncHermesConversationMessages(paths, logger, input) {
21608
21678
  if (candidateMessages.length === 0) {
21609
21679
  continue;
21610
21680
  }
21681
+ const missingCandidateMessages = candidateMessages.filter(
21682
+ (message, index) => !isRepresentedHermesRow(representedRows, message, index)
21683
+ );
21684
+ if (missingCandidateMessages.length === 0) {
21685
+ continue;
21686
+ }
21611
21687
  const profile = await resolveConversationProfileTarget(
21612
21688
  paths,
21613
21689
  candidate.profileName
@@ -21624,7 +21700,7 @@ async function syncHermesConversationMessages(paths, logger, input) {
21624
21700
  profileUid: profile.profileUid,
21625
21701
  profileDisplayName: profile.profileDisplayName,
21626
21702
  sessionId: candidate.session.id,
21627
- messages: candidateMessages
21703
+ messages: missingCandidateMessages
21628
21704
  })
21629
21705
  );
21630
21706
  } catch (error) {
@@ -21650,6 +21726,14 @@ async function syncHermesConversationMessages(paths, logger, input) {
21650
21726
  exactKeys.forEach((key) => knownExactKeys.add(key));
21651
21727
  }
21652
21728
  if (appendedMessages.length === 0) {
21729
+ if (duplicateCleanup.removedCount > 0) {
21730
+ await store.writeSnapshot(input.conversationId, snapshot);
21731
+ const currentManifest = await store.readManifest(input.conversationId);
21732
+ const stats2 = buildConversationStats(currentManifest, snapshot);
21733
+ const nextManifest2 = { ...currentManifest, stats: stats2 };
21734
+ await store.writeManifest(nextManifest2);
21735
+ await upsertConversationStats(paths, toStatsIndexRecord(nextManifest2, stats2));
21736
+ }
21653
21737
  return result;
21654
21738
  }
21655
21739
  await store.writeSnapshot(input.conversationId, {
@@ -21747,7 +21831,7 @@ async function importHermesSession(input) {
21747
21831
  id: conversationId,
21748
21832
  schema_version: 1,
21749
21833
  kind: "direct",
21750
- title: normalizeTitle(title),
21834
+ title: normalizeTitle2(title),
21751
21835
  title_source: title ? "hermes" : "default",
21752
21836
  status: "active",
21753
21837
  hermes_session_id: sessionId,
@@ -22019,6 +22103,293 @@ function collectKnownHermesRowKeys(snapshot) {
22019
22103
  }
22020
22104
  return keys;
22021
22105
  }
22106
+ function collectRepresentedHermesRows(paths, snapshot) {
22107
+ const rows = {
22108
+ syntheticUserTexts: /* @__PURE__ */ new Set(),
22109
+ toolCallIds: /* @__PURE__ */ new Set(),
22110
+ runWindows: []
22111
+ };
22112
+ for (const run of snapshot.runs) {
22113
+ collectRunHermesMessageWindows(run).forEach(
22114
+ (window) => rows.runWindows.push(window)
22115
+ );
22116
+ const userMessage = snapshot.messages.find(
22117
+ (message) => message.id === run.trigger_message_id
22118
+ );
22119
+ if (userMessage) {
22120
+ collectSyntheticRunInputTexts(paths, userMessage).forEach(
22121
+ (text) => rows.syntheticUserTexts.add(hashText(text))
22122
+ );
22123
+ }
22124
+ const assistantMessage = snapshot.messages.find(
22125
+ (message) => message.id === run.assistant_message_id
22126
+ );
22127
+ if (assistantMessage) {
22128
+ collectAgentEventIds(assistantMessage).forEach(
22129
+ (id) => rows.toolCallIds.add(id)
22130
+ );
22131
+ }
22132
+ }
22133
+ return rows;
22134
+ }
22135
+ function pruneStrictImportedDuplicateMessages(paths, snapshot) {
22136
+ if (snapshot.runs.length === 0) {
22137
+ return { snapshot, removedCount: 0 };
22138
+ }
22139
+ const messages2 = snapshot.messages.filter(
22140
+ (message) => !isStrictImportedDuplicateRunMessage(paths, snapshot, message)
22141
+ );
22142
+ const removedCount = snapshot.messages.length - messages2.length;
22143
+ return removedCount > 0 ? { snapshot: { ...snapshot, messages: messages2 }, removedCount } : { snapshot, removedCount: 0 };
22144
+ }
22145
+ function isStrictImportedDuplicateRunMessage(paths, snapshot, message) {
22146
+ if (!isHermesImportedMessage2(message)) {
22147
+ return false;
22148
+ }
22149
+ if (snapshot.runs.some(
22150
+ (run) => run.trigger_message_id === message.id || run.assistant_message_id === message.id
22151
+ )) {
22152
+ return false;
22153
+ }
22154
+ const messageSessionIds = collectMessageHermesSessionIds(message);
22155
+ if (messageSessionIds.size === 0) {
22156
+ return false;
22157
+ }
22158
+ return snapshot.runs.some((run) => {
22159
+ if (!runSessionMatchesMessage(run, messageSessionIds)) {
22160
+ return false;
22161
+ }
22162
+ if (!isMessageInsideRunCleanupWindow(message, run)) {
22163
+ return false;
22164
+ }
22165
+ if (message.role === "user") {
22166
+ const user = snapshot.messages.find(
22167
+ (item) => item.id === run.trigger_message_id
22168
+ );
22169
+ return user ? isDuplicateImportedRunUser(paths, user, message) : false;
22170
+ }
22171
+ if (message.role === "assistant" || message.role === "tool") {
22172
+ const assistant = snapshot.messages.find(
22173
+ (item) => item.id === run.assistant_message_id
22174
+ );
22175
+ return assistant ? isDuplicateImportedRunAssistant(assistant, message) : false;
22176
+ }
22177
+ return false;
22178
+ });
22179
+ }
22180
+ function isDuplicateImportedRunUser(paths, user, imported) {
22181
+ const importedText = normalizedDuplicateText(imported);
22182
+ if (!importedText) {
22183
+ return false;
22184
+ }
22185
+ if (importedText === normalizedDuplicateText(user)) {
22186
+ return true;
22187
+ }
22188
+ return collectSyntheticRunInputTexts(paths, user).some(
22189
+ (text) => normalizedDuplicateTextValue(text) === importedText
22190
+ );
22191
+ }
22192
+ function isDuplicateImportedRunAssistant(assistant, imported) {
22193
+ const importedText = normalizedDuplicateText(imported);
22194
+ if (importedText && importedText === normalizedDuplicateText(assistant)) {
22195
+ return true;
22196
+ }
22197
+ const importedToolIds = collectAgentEventIds(imported);
22198
+ if (importedToolIds.size === 0) {
22199
+ return false;
22200
+ }
22201
+ const assistantToolIds = collectAgentEventIds(assistant);
22202
+ return [...importedToolIds].every((id) => assistantToolIds.has(id));
22203
+ }
22204
+ function collectMessageHermesSessionIds(message) {
22205
+ const sessionIds = /* @__PURE__ */ new Set();
22206
+ const hermes = toRecord12(message.hermes);
22207
+ const sessionId = readString12(hermes, "session_id");
22208
+ if (sessionId) {
22209
+ sessionIds.add(sessionId);
22210
+ }
22211
+ for (const row of readHermesRawMessageRows(message.raw)) {
22212
+ const rowSessionId = readString12(row, "session_id");
22213
+ if (rowSessionId) {
22214
+ sessionIds.add(rowSessionId);
22215
+ }
22216
+ }
22217
+ return sessionIds;
22218
+ }
22219
+ function runSessionMatchesMessage(run, messageSessionIds) {
22220
+ return collectRunHermesSessionIds(run).some(
22221
+ (sessionId) => messageSessionIds.has(sessionId)
22222
+ );
22223
+ }
22224
+ function collectRunHermesSessionIds(run) {
22225
+ return normalizeSessionIds([
22226
+ run.hermes_session_id,
22227
+ run.hermes_message_watermark?.before?.session_id,
22228
+ run.hermes_message_watermark?.after?.session_id
22229
+ ]);
22230
+ }
22231
+ function isMessageInsideRunCleanupWindow(message, run) {
22232
+ if (run.status === "queued" || run.status === "running" || run.status === "unknown") {
22233
+ return false;
22234
+ }
22235
+ const messageAt = parseIsoMillis(message.created_at);
22236
+ const startedAt = parseIsoMillis(run.started_at);
22237
+ const completedAt = run.completed_at ? parseIsoMillis(run.completed_at) : void 0;
22238
+ if (messageAt === void 0 || startedAt === void 0) {
22239
+ return false;
22240
+ }
22241
+ const lowerBound = startedAt - 10 * 60 * 1e3;
22242
+ const upperBound = (completedAt ?? startedAt) + 10 * 60 * 1e3;
22243
+ return messageAt >= lowerBound && messageAt <= upperBound;
22244
+ }
22245
+ function normalizedDuplicateText(message) {
22246
+ return normalizedDuplicateTextValue(messageText2(message));
22247
+ }
22248
+ function normalizedDuplicateTextValue(value) {
22249
+ return value.replace(/\r\n/gu, "\n").trim();
22250
+ }
22251
+ function collectRunHermesMessageWindows(run) {
22252
+ const before = normalizeWatermarkPoint(
22253
+ run.hermes_message_watermark?.before,
22254
+ run.hermes_session_id
22255
+ );
22256
+ if (!before) {
22257
+ return [];
22258
+ }
22259
+ const after = normalizeWatermarkPoint(
22260
+ run.hermes_message_watermark?.after,
22261
+ run.hermes_session_id
22262
+ );
22263
+ const sessionId = before.session_id?.trim() || run.hermes_session_id?.trim();
22264
+ if (!sessionId) {
22265
+ return [];
22266
+ }
22267
+ return [
22268
+ {
22269
+ runId: run.id,
22270
+ sessionId,
22271
+ status: run.status,
22272
+ before,
22273
+ ...after && (after.session_id ?? sessionId) === sessionId ? { after } : {},
22274
+ startedAtMs: parseIsoMillis(run.started_at),
22275
+ completedAtMs: run.completed_at ? parseIsoMillis(run.completed_at) : void 0
22276
+ }
22277
+ ];
22278
+ }
22279
+ function normalizeWatermarkPoint(point, fallbackSessionId) {
22280
+ if (!point || typeof point.message_count !== "number" || !Number.isFinite(point.message_count)) {
22281
+ return null;
22282
+ }
22283
+ const sessionId = point.session_id?.trim() || fallbackSessionId?.trim();
22284
+ return {
22285
+ source: point.source,
22286
+ ...sessionId ? { session_id: sessionId } : {},
22287
+ message_count: Math.max(0, Math.trunc(point.message_count)),
22288
+ ...typeof point.max_message_id === "number" && Number.isFinite(point.max_message_id) ? { max_message_id: point.max_message_id } : {},
22289
+ ...typeof point.max_timestamp === "number" && Number.isFinite(point.max_timestamp) ? { max_timestamp: point.max_timestamp } : {},
22290
+ captured_at: point.captured_at
22291
+ };
22292
+ }
22293
+ function collectSyntheticRunInputTexts(paths, message) {
22294
+ if (message.role !== "user") {
22295
+ return [];
22296
+ }
22297
+ const attachmentLines = message.parts.filter((part) => Boolean(part.blob)).filter((part) => !isVoicePart(part)).map((part) => {
22298
+ const label = part.filename ?? part.blob;
22299
+ const mime = part.mime ? `, ${part.mime}` : "";
22300
+ const size = part.size ? `, ${part.size} bytes` : "";
22301
+ return `- ${label}${mime}${size}: ${part.local_path ?? blobPath(paths, part.blob)}`;
22302
+ });
22303
+ if (attachmentLines.length === 0) {
22304
+ return [];
22305
+ }
22306
+ const content = messageText2(message);
22307
+ const prefix = content ? `${content}
22308
+
22309
+ ` : "";
22310
+ return [
22311
+ `${prefix}Attachments available on this computer:
22312
+ ${attachmentLines.join("\n")}`
22313
+ ];
22314
+ }
22315
+ function collectAgentEventIds(message) {
22316
+ const ids = /* @__PURE__ */ new Set();
22317
+ for (const event of message.agent_events ?? []) {
22318
+ if (event.id) {
22319
+ ids.add(event.id);
22320
+ }
22321
+ }
22322
+ for (const block of message.blocks ?? []) {
22323
+ if (block.type !== "agent_events") {
22324
+ continue;
22325
+ }
22326
+ for (const event of block.events) {
22327
+ if (event.id) {
22328
+ ids.add(event.id);
22329
+ }
22330
+ }
22331
+ }
22332
+ return ids;
22333
+ }
22334
+ function isRepresentedHermesRow(represented, row, index) {
22335
+ const role = normalizeMessageRole(row.role);
22336
+ if (represented.runWindows.some(
22337
+ (window) => isRowInsideRunWindow(window, row, role)
22338
+ )) {
22339
+ return true;
22340
+ }
22341
+ if (role === "user" && represented.syntheticUserTexts.has(hashText(normalizeContent2(row.content)))) {
22342
+ return true;
22343
+ }
22344
+ if (role === "assistant") {
22345
+ const toolCalls = readHermesToolCalls(row);
22346
+ return toolCalls.length > 0 && toolCalls.every(
22347
+ (toolCall) => toolCall.id && represented.toolCallIds.has(toolCall.id)
22348
+ );
22349
+ }
22350
+ if (role === "tool") {
22351
+ const id = readString12(row, "tool_call_id") ?? readString12(row, "tool_id") ?? readString12(row, "call_id");
22352
+ if (id) {
22353
+ return represented.toolCallIds.has(id);
22354
+ }
22355
+ const key = hermesRowKey(row, index);
22356
+ return represented.toolCallIds.has(key);
22357
+ }
22358
+ return false;
22359
+ }
22360
+ function isRowInsideRunWindow(window, row, role) {
22361
+ if (role === "system") {
22362
+ return false;
22363
+ }
22364
+ if ((readString12(row, "session_id") ?? "") !== window.sessionId) {
22365
+ return false;
22366
+ }
22367
+ const hasClosedAfter = Boolean(window.after);
22368
+ const allowOpenEnded = window.status === "running";
22369
+ const allowTerminalGrace = !hasClosedAfter && (window.status === "cancelled" || window.status === "failed") && window.completedAtMs !== void 0;
22370
+ if (!hasClosedAfter && !allowOpenEnded && !allowTerminalGrace) {
22371
+ return false;
22372
+ }
22373
+ const position = rowSessionPosition(row);
22374
+ if (window.before.source !== "none" && position !== void 0 && position > window.before.message_count && (window.after ? position <= window.after.message_count : allowOpenEnded)) {
22375
+ return true;
22376
+ }
22377
+ const rowId = readNumber3(row.id);
22378
+ if (rowId !== null && window.before.max_message_id !== void 0 && rowId > window.before.max_message_id && (window.after?.max_message_id !== void 0 ? rowId <= window.after.max_message_id : allowOpenEnded)) {
22379
+ return true;
22380
+ }
22381
+ const rowTimeMs = hermesTimestampMillis(row.timestamp);
22382
+ if (rowTimeMs === void 0) {
22383
+ return false;
22384
+ }
22385
+ const beforeTimeMs = hermesTimestampMillis(window.before.max_timestamp);
22386
+ const lowerTimeMs = beforeTimeMs ?? (window.startedAtMs ?? 0) - 5e3;
22387
+ const upperTimeMs = hermesTimestampMillis(window.after?.max_timestamp) ?? (allowTerminalGrace && window.completedAtMs !== void 0 ? window.completedAtMs + 2 * 60 * 1e3 : allowOpenEnded ? Number.POSITIVE_INFINITY : void 0);
22388
+ return upperTimeMs !== void 0 && (beforeTimeMs !== void 0 ? rowTimeMs > lowerTimeMs : rowTimeMs >= lowerTimeMs) && rowTimeMs <= upperTimeMs;
22389
+ }
22390
+ function isVoicePart(part) {
22391
+ return part.kind === "voice" || part.is_voice_note === true;
22392
+ }
22022
22393
  function collectMessageHermesRowKeys(message) {
22023
22394
  const keys = [];
22024
22395
  readHermesRawMessageRows(message.raw).forEach((row, index) => {
@@ -22072,6 +22443,21 @@ function representedMessageSignature(message) {
22072
22443
  function hashText(value) {
22073
22444
  return createHash6("sha256").update(value).digest("hex");
22074
22445
  }
22446
+ function rowSessionPosition(row) {
22447
+ const position = row[HERMES_ROW_SESSION_POSITION];
22448
+ return typeof position === "number" && Number.isFinite(position) ? position : void 0;
22449
+ }
22450
+ function hermesTimestampMillis(value) {
22451
+ const numeric = readNumber3(value);
22452
+ if (numeric === null || numeric <= 0) {
22453
+ return void 0;
22454
+ }
22455
+ return numeric > 1e10 ? numeric : numeric * 1e3;
22456
+ }
22457
+ function parseIsoMillis(value) {
22458
+ const parsed = Date.parse(value);
22459
+ return Number.isFinite(parsed) ? parsed : void 0;
22460
+ }
22075
22461
  function compareLinkMessagesByCreatedAt(left, right) {
22076
22462
  return Date.parse(left.created_at) - Date.parse(right.created_at) || left.id.localeCompare(right.id);
22077
22463
  }
@@ -22165,6 +22551,59 @@ async function readExistingHermesConversations(store, conversationIds) {
22165
22551
  }
22166
22552
  return conversations;
22167
22553
  }
22554
+ async function archiveKnownHermesConversation(input) {
22555
+ const conversationIds = findKnownConversationIdsForCandidate(
22556
+ input.knownHermesSessions,
22557
+ input.candidate
22558
+ );
22559
+ if (conversationIds.length === 0) {
22560
+ return 0;
22561
+ }
22562
+ const archivedAt = readString12(input.candidate.session, "archived_at") ?? (/* @__PURE__ */ new Date()).toISOString();
22563
+ let archivedCount = 0;
22564
+ for (const conversation of await readExistingHermesConversations(
22565
+ input.store,
22566
+ conversationIds
22567
+ )) {
22568
+ if (conversation.manifest.status !== "active") {
22569
+ continue;
22570
+ }
22571
+ const nextManifest = {
22572
+ ...conversation.manifest,
22573
+ status: "archived",
22574
+ updated_at: archivedAt,
22575
+ archived_at: archivedAt,
22576
+ hermes_session_ids: normalizeSessionIds([
22577
+ conversation.manifest.hermes_session_id,
22578
+ ...conversation.manifest.hermes_session_ids ?? [],
22579
+ ...conversation.manifest.hermes_lineage?.session_ids ?? [],
22580
+ ...lineageSessionIds(input.candidate)
22581
+ ]),
22582
+ ...lineageManifestPatch(input.candidate)
22583
+ };
22584
+ const stats = buildConversationStats(nextManifest, conversation.snapshot);
22585
+ const archivedManifest = { ...nextManifest, stats };
22586
+ await input.store.writeManifest(archivedManifest);
22587
+ await input.store.appendEvent(conversation.conversationId, {
22588
+ type: "conversation.archived",
22589
+ payload: {
22590
+ archived_at: archivedAt,
22591
+ source: "hermes",
22592
+ hermes_session_id: input.candidate.session.id
22593
+ }
22594
+ });
22595
+ const eventManifest = await input.store.readManifest(conversation.conversationId);
22596
+ const eventStats = buildConversationStats(eventManifest, conversation.snapshot);
22597
+ const indexedManifest = { ...eventManifest, stats: eventStats };
22598
+ await input.store.writeManifest(indexedManifest);
22599
+ await upsertConversationStats(
22600
+ input.paths,
22601
+ toStatsIndexRecord(indexedManifest, eventStats)
22602
+ );
22603
+ archivedCount += 1;
22604
+ }
22605
+ return archivedCount;
22606
+ }
22168
22607
  function selectCanonicalHermesConversation(conversations) {
22169
22608
  const ranked = [...conversations].sort((left, right) => {
22170
22609
  const rightScore = canonicalConversationScore(right);
@@ -22277,7 +22716,7 @@ function mergeHermesLineageIntoManifest(input) {
22277
22716
  };
22278
22717
  const title = deriveHermesConversationTitle(input.candidate, input.snapshot);
22279
22718
  if (title && canSyncHermesTitle(input.manifest)) {
22280
- nextBase.title = normalizeTitle(title);
22719
+ nextBase.title = normalizeTitle2(title);
22281
22720
  nextBase.title_source = "hermes";
22282
22721
  }
22283
22722
  const baseStats = buildConversationStats(nextBase, input.snapshot);
@@ -23066,9 +23505,15 @@ async function readHermesSessionMessages(candidate) {
23066
23505
  readJsonlMessages(candidate.profileName, candidate.session.id)
23067
23506
  ]);
23068
23507
  const selected = jsonlMessages.length > dbMessages.length ? jsonlMessages : dbMessages;
23069
- return selected.map(
23070
- (message) => readString12(message, "session_id") ? message : { ...message, session_id: candidate.session.id }
23071
- );
23508
+ return selected.map((message, index) => {
23509
+ const normalized = readString12(message, "session_id") ? message : { ...message, session_id: candidate.session.id };
23510
+ Object.defineProperty(normalized, HERMES_ROW_SESSION_POSITION, {
23511
+ value: index + 1,
23512
+ enumerable: false,
23513
+ configurable: true
23514
+ });
23515
+ return normalized;
23516
+ });
23072
23517
  }
23073
23518
  async function readStateDbMessages(dbPath, sessionId) {
23074
23519
  if (!await isFile(dbPath)) {
@@ -23310,7 +23755,7 @@ function senderForRole(input) {
23310
23755
  function firstUserText(snapshot) {
23311
23756
  return snapshot.messages.find((message) => message.role === "user")?.parts.find((part) => part.type === "text")?.text?.slice(0, 80);
23312
23757
  }
23313
- function normalizeTitle(value) {
23758
+ function normalizeTitle2(value) {
23314
23759
  const normalized = value?.replace(/\s+/gu, " ").trim();
23315
23760
  return normalized || DEFAULT_CONVERSATION_TITLE;
23316
23761
  }
@@ -23423,6 +23868,10 @@ function isHiddenSession(session) {
23423
23868
  const visibility = readString12(session, "visibility")?.toLowerCase();
23424
23869
  return Boolean(source && HIDDEN_SESSION_SOURCES.has(source)) || readBoolean2(session.hidden) || readBoolean2(session.archived) || Boolean(readString12(session, "archived_at")) || status === "hidden" || status === "archived" || visibility === "hidden" || visibility === "hide";
23425
23870
  }
23871
+ function isArchivedSession(session) {
23872
+ const status = readString12(session, "status")?.toLowerCase();
23873
+ return readBoolean2(session.archived) || Boolean(readString12(session, "archived_at")) || status === "archived";
23874
+ }
23426
23875
  function readTableColumns2(db, tableName) {
23427
23876
  try {
23428
23877
  const rows = db.prepare(`PRAGMA table_info(${quoteIdentifier(tableName)})`).all();
@@ -24181,10 +24630,10 @@ function parseHermesApiCapabilities(payload) {
24181
24630
  sessionKeyHeader: readString14(features, "session_key_header")
24182
24631
  };
24183
24632
  }
24184
- async function callHermesApi(path38, init, options) {
24633
+ async function callHermesApi(path39, init, options) {
24185
24634
  const method = init.method ?? "GET";
24186
24635
  const startedAt = Date.now();
24187
- void options.logger?.debug("hermes_api_request_started", { method, path: path38 });
24636
+ void options.logger?.debug("hermes_api_request_started", { method, path: path39 });
24188
24637
  const availability = await ensureHermesApiServerAvailable({
24189
24638
  fetchImpl: options.fetchImpl,
24190
24639
  logger: options.logger,
@@ -24193,7 +24642,7 @@ async function callHermesApi(path38, init, options) {
24193
24642
  });
24194
24643
  let config = availability.configResult.apiServer;
24195
24644
  const fetcher = options.fetchImpl ?? fetch;
24196
- const request = () => fetchHermesApi(fetcher, config, path38, init, options);
24645
+ const request = () => fetchHermesApi(fetcher, config, path39, init, options);
24197
24646
  let response;
24198
24647
  try {
24199
24648
  response = await request();
@@ -24201,7 +24650,7 @@ async function callHermesApi(path38, init, options) {
24201
24650
  logHermesApiError(
24202
24651
  options.logger,
24203
24652
  method,
24204
- path38,
24653
+ path39,
24205
24654
  options.profileName,
24206
24655
  startedAt,
24207
24656
  error
@@ -24212,7 +24661,7 @@ async function callHermesApi(path38, init, options) {
24212
24661
  logHermesApiResponse(
24213
24662
  options.logger,
24214
24663
  method,
24215
- path38,
24664
+ path39,
24216
24665
  options.profileName,
24217
24666
  startedAt,
24218
24667
  response
@@ -24221,7 +24670,7 @@ async function callHermesApi(path38, init, options) {
24221
24670
  }
24222
24671
  void options.logger?.warn("hermes_api_request_retrying_after_401", {
24223
24672
  method,
24224
- path: path38,
24673
+ path: path39,
24225
24674
  profile: options.profileName ?? "default",
24226
24675
  port: config.port ?? null,
24227
24676
  duration_ms: Date.now() - startedAt
@@ -24240,7 +24689,7 @@ async function callHermesApi(path38, init, options) {
24240
24689
  logHermesApiError(
24241
24690
  options.logger,
24242
24691
  method,
24243
- path38,
24692
+ path39,
24244
24693
  options.profileName,
24245
24694
  startedAt,
24246
24695
  error
@@ -24250,7 +24699,7 @@ async function callHermesApi(path38, init, options) {
24250
24699
  logHermesApiResponse(
24251
24700
  options.logger,
24252
24701
  method,
24253
- path38,
24702
+ path39,
24254
24703
  options.profileName,
24255
24704
  startedAt,
24256
24705
  response
@@ -24260,7 +24709,7 @@ async function callHermesApi(path38, init, options) {
24260
24709
  }
24261
24710
  void options.logger?.warn("hermes_api_request_repairing_after_401", {
24262
24711
  method,
24263
- path: path38,
24712
+ path: path39,
24264
24713
  profile: options.profileName ?? "default",
24265
24714
  port: config.port ?? null,
24266
24715
  duration_ms: Date.now() - startedAt
@@ -24281,7 +24730,7 @@ async function callHermesApi(path38, init, options) {
24281
24730
  logHermesApiError(
24282
24731
  options.logger,
24283
24732
  method,
24284
- path38,
24733
+ path39,
24285
24734
  options.profileName,
24286
24735
  startedAt,
24287
24736
  error
@@ -24291,21 +24740,21 @@ async function callHermesApi(path38, init, options) {
24291
24740
  logHermesApiResponse(
24292
24741
  options.logger,
24293
24742
  method,
24294
- path38,
24743
+ path39,
24295
24744
  options.profileName,
24296
24745
  startedAt,
24297
24746
  response
24298
24747
  );
24299
24748
  return response;
24300
24749
  }
24301
- async function fetchHermesApi(fetcher, config, path38, init, options) {
24750
+ async function fetchHermesApi(fetcher, config, path39, init, options) {
24302
24751
  const headers = new Headers(init.headers);
24303
24752
  headers.set("accept", headers.get("accept") ?? "application/json");
24304
24753
  if (config.key) {
24305
24754
  headers.set("x-api-key", config.key);
24306
24755
  headers.set("authorization", `Bearer ${config.key}`);
24307
24756
  }
24308
- return await fetcher(`http://127.0.0.1:${config.port}${path38}`, {
24757
+ return await fetcher(`http://127.0.0.1:${config.port}${path39}`, {
24309
24758
  ...init,
24310
24759
  headers
24311
24760
  }).catch((error) => {
@@ -24314,10 +24763,10 @@ async function fetchHermesApi(fetcher, config, path38, init, options) {
24314
24763
  }
24315
24764
  void options.logger?.warn("hermes_api_server_connect_failed", {
24316
24765
  method: String(init.method ?? "GET").toUpperCase(),
24317
- path: path38,
24766
+ path: path39,
24318
24767
  profile: options.profileName ?? "default",
24319
24768
  port: config.port ?? null,
24320
- url: `http://127.0.0.1:${config.port}${path38}`,
24769
+ url: `http://127.0.0.1:${config.port}${path39}`,
24321
24770
  error: error instanceof Error ? error.message : String(error)
24322
24771
  });
24323
24772
  throw new LinkHttpError(
@@ -24327,10 +24776,10 @@ async function fetchHermesApi(fetcher, config, path38, init, options) {
24327
24776
  );
24328
24777
  });
24329
24778
  }
24330
- function logHermesApiResponse(logger, method, path38, profileName, startedAt, response) {
24779
+ function logHermesApiResponse(logger, method, path39, profileName, startedAt, response) {
24331
24780
  const fields = {
24332
24781
  method,
24333
- path: path38,
24782
+ path: path39,
24334
24783
  profile: profileName ?? "default",
24335
24784
  status: response.status,
24336
24785
  duration_ms: Date.now() - startedAt
@@ -24351,10 +24800,10 @@ async function logHermesApiFailureResponse(logger, fields, response) {
24351
24800
  ...upstreamError ? { upstream_error: upstreamError } : {}
24352
24801
  });
24353
24802
  }
24354
- function logHermesApiError(logger, method, path38, profileName, startedAt, error) {
24803
+ function logHermesApiError(logger, method, path39, profileName, startedAt, error) {
24355
24804
  void logger?.warn("hermes_api_request_failed", {
24356
24805
  method,
24357
- path: path38,
24806
+ path: path39,
24358
24807
  profile: profileName ?? "default",
24359
24808
  duration_ms: Date.now() - startedAt,
24360
24809
  ...error instanceof LinkHttpError ? { status: error.status, code: error.code } : {},
@@ -26790,6 +27239,127 @@ function isNodeError17(error, code) {
26790
27239
  return typeof error === "object" && error !== null && "code" in error && error.code === code;
26791
27240
  }
26792
27241
 
27242
+ // src/conversations/hermes-message-watermark.ts
27243
+ import { stat as stat18, readFile as readFile16 } from "fs/promises";
27244
+ import path27 from "path";
27245
+ async function readHermesMessageWatermark(input) {
27246
+ const profileName = input.profileName?.trim() || "default";
27247
+ const sessionId = input.sessionId.trim();
27248
+ const profileDir = resolveHermesProfileDir(profileName);
27249
+ const dbPath = path27.join(profileDir, "state.db");
27250
+ const [dbWatermark, jsonlWatermark] = await Promise.all([
27251
+ readStateDbMessageWatermark(dbPath, sessionId),
27252
+ readJsonlMessageWatermark(profileName, sessionId)
27253
+ ]);
27254
+ const selected = (jsonlWatermark.message_count ?? 0) > (dbWatermark.message_count ?? 0) ? jsonlWatermark : dbWatermark;
27255
+ return {
27256
+ ...selected,
27257
+ session_id: sessionId,
27258
+ captured_at: (/* @__PURE__ */ new Date()).toISOString()
27259
+ };
27260
+ }
27261
+ async function readStateDbMessageWatermark(dbPath, sessionId) {
27262
+ if (!await isFile3(dbPath)) {
27263
+ return { source: "none", message_count: 0 };
27264
+ }
27265
+ let db = null;
27266
+ try {
27267
+ db = openSqliteDatabase(dbPath, {
27268
+ readonly: true,
27269
+ timeout: 1e3
27270
+ });
27271
+ const columns = readTableColumns4(db, "messages");
27272
+ if (!columns.has("session_id")) {
27273
+ return { source: "none", message_count: 0 };
27274
+ }
27275
+ const idExpression = columns.has("id") ? "MAX(CASE WHEN typeof(id) IN ('integer', 'real') THEN id ELSE NULL END) AS max_message_id" : "NULL AS max_message_id";
27276
+ const timestampExpression = columns.has("timestamp") ? "MAX(timestamp) AS max_timestamp" : "NULL AS max_timestamp";
27277
+ const row = db.prepare(
27278
+ `
27279
+ SELECT COUNT(*) AS message_count, ${idExpression}, ${timestampExpression}
27280
+ FROM messages
27281
+ WHERE session_id = ?
27282
+ `
27283
+ ).get(sessionId);
27284
+ return {
27285
+ source: "state_db",
27286
+ message_count: readNumber5(row.message_count) ?? 0,
27287
+ ...readNumber5(row.max_message_id) !== null ? { max_message_id: readNumber5(row.max_message_id) } : {},
27288
+ ...readNumber5(row.max_timestamp) !== null ? { max_timestamp: readNumber5(row.max_timestamp) } : {}
27289
+ };
27290
+ } catch {
27291
+ return { source: "none", message_count: 0 };
27292
+ } finally {
27293
+ db?.close();
27294
+ }
27295
+ }
27296
+ async function readJsonlMessageWatermark(profileName, sessionId) {
27297
+ if (!/^[A-Za-z0-9._:-]{1,160}$/u.test(sessionId)) {
27298
+ return { source: "none", message_count: 0 };
27299
+ }
27300
+ const profileDir = resolveHermesProfileDir(profileName);
27301
+ const sessionsDir = await readHermesSessionsDir(profileName).then((value) => value.sessionsDir).catch(() => path27.join(profileDir, "sessions"));
27302
+ const transcriptPath = path27.join(sessionsDir, `${sessionId}.jsonl`);
27303
+ const raw = await readFile16(transcriptPath, "utf8").catch(() => "");
27304
+ if (!raw.trim()) {
27305
+ return { source: "none", message_count: 0 };
27306
+ }
27307
+ let messageCount = 0;
27308
+ let maxMessageId;
27309
+ let maxTimestamp;
27310
+ for (const line of raw.split(/\r?\n/u)) {
27311
+ if (!line.trim()) {
27312
+ continue;
27313
+ }
27314
+ try {
27315
+ const parsed = JSON.parse(line);
27316
+ if (!readString18(parsed, "role")) {
27317
+ continue;
27318
+ }
27319
+ messageCount += 1;
27320
+ const id = readNumber5(parsed.id);
27321
+ const timestamp = readNumber5(parsed.timestamp) ?? readNumber5(parsed.created_at) ?? readNumber5(parsed.createdAt);
27322
+ if (id !== null) {
27323
+ maxMessageId = maxMessageId === void 0 ? id : Math.max(maxMessageId, id);
27324
+ }
27325
+ if (timestamp !== null) {
27326
+ maxTimestamp = maxTimestamp === void 0 ? timestamp : Math.max(maxTimestamp, timestamp);
27327
+ }
27328
+ } catch {
27329
+ continue;
27330
+ }
27331
+ }
27332
+ return {
27333
+ source: messageCount > 0 ? "jsonl" : "none",
27334
+ message_count: messageCount,
27335
+ ...maxMessageId !== void 0 ? { max_message_id: maxMessageId } : {},
27336
+ ...maxTimestamp !== void 0 ? { max_timestamp: maxTimestamp } : {}
27337
+ };
27338
+ }
27339
+ function readTableColumns4(db, tableName) {
27340
+ try {
27341
+ const rows = db.prepare(`PRAGMA table_info(${quoteIdentifier3(tableName)})`).all();
27342
+ return new Set(
27343
+ rows.map((row) => typeof row.name === "string" ? row.name : "").filter(Boolean)
27344
+ );
27345
+ } catch {
27346
+ return /* @__PURE__ */ new Set();
27347
+ }
27348
+ }
27349
+ function quoteIdentifier3(value) {
27350
+ return `"${value.replaceAll('"', '""')}"`;
27351
+ }
27352
+ async function isFile3(filePath) {
27353
+ return stat18(filePath).then((value) => value.isFile()).catch(() => false);
27354
+ }
27355
+ function readString18(payload, key) {
27356
+ const value = payload[key];
27357
+ return typeof value === "string" && value.trim() ? value.trim() : null;
27358
+ }
27359
+ function readNumber5(value) {
27360
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
27361
+ }
27362
+
26793
27363
  // src/conversations/run-tool-event-ids.ts
26794
27364
  import { createHash as createHash7 } from "crypto";
26795
27365
  var RunToolEventIdCoalescer = class {
@@ -26883,7 +27453,7 @@ var RunToolEventIdCoalescer = class {
26883
27453
  }
26884
27454
  };
26885
27455
  function readToolEventType(event) {
26886
- const type = readString18(event.payload, "type") ?? readString18(event.payload, "event") ?? event.payloadType;
27456
+ const type = readString19(event.payload, "type") ?? readString19(event.payload, "event") ?? event.payloadType;
26887
27457
  return type.startsWith("tool.") ? type : null;
26888
27458
  }
26889
27459
  function isTerminalToolEvent(type) {
@@ -26894,14 +27464,14 @@ function hasStableToolEventId(payload) {
26894
27464
  const call = toRecord17(payload.tool_call ?? payload.toolCall);
26895
27465
  const fn = toRecord17(call.function ?? payload.function);
26896
27466
  return Boolean(
26897
- readString18(payload, "tool_call_id") ?? readString18(payload, "toolCallId") ?? readString18(payload, "tool_id") ?? readString18(payload, "call_id") ?? readString18(payload, "id") ?? readString18(tool, "id") ?? readString18(call, "id") ?? readString18(fn, "id")
27467
+ readString19(payload, "tool_call_id") ?? readString19(payload, "toolCallId") ?? readString19(payload, "tool_id") ?? readString19(payload, "call_id") ?? readString19(payload, "id") ?? readString19(tool, "id") ?? readString19(call, "id") ?? readString19(fn, "id")
26898
27468
  );
26899
27469
  }
26900
27470
  function readToolName2(payload) {
26901
27471
  const tool = toRecord17(payload.tool);
26902
27472
  const call = toRecord17(payload.tool_call ?? payload.toolCall);
26903
27473
  const fn = toRecord17(call.function ?? payload.function);
26904
- return readString18(payload, "tool_name") ?? readString18(payload, "toolName") ?? readString18(payload, "name") ?? readString18(payload, "tool") ?? readString18(tool, "name") ?? readString18(call, "name") ?? readString18(fn, "name") ?? "tool";
27474
+ return readString19(payload, "tool_name") ?? readString19(payload, "toolName") ?? readString19(payload, "name") ?? readString19(payload, "tool") ?? readString19(tool, "name") ?? readString19(call, "name") ?? readString19(fn, "name") ?? "tool";
26905
27475
  }
26906
27476
  function withGeneratedToolEventId(event, id) {
26907
27477
  return {
@@ -26958,7 +27528,7 @@ function stableStringify2(value) {
26958
27528
  function hashStableValue(value) {
26959
27529
  return createHash7("sha256").update(value).digest("hex").slice(0, 16);
26960
27530
  }
26961
- function readString18(payload, key) {
27531
+ function readString19(payload, key) {
26962
27532
  const value = payload[key];
26963
27533
  return typeof value === "string" && value.trim() ? value.trim() : null;
26964
27534
  }
@@ -26990,8 +27560,8 @@ function normalizeHermesStreamEvent(event) {
26990
27560
  };
26991
27561
  }
26992
27562
  if (event.eventName === "hermes.tool.progress") {
26993
- const toolName = readString19(event.payload, "tool") ?? readString19(event.payload, "name") ?? "tool";
26994
- const preview = readString19(event.payload, "label") ?? readString19(event.payload, "preview") ?? toolName;
27563
+ const toolName = readString20(event.payload, "tool") ?? readString20(event.payload, "name") ?? "tool";
27564
+ const preview = readString20(event.payload, "label") ?? readString20(event.payload, "preview") ?? toolName;
26995
27565
  return {
26996
27566
  ...event,
26997
27567
  payloadType: "tool.started",
@@ -27043,7 +27613,7 @@ function normalizeReasoningEvent(event) {
27043
27613
  if (type !== "tool.progress" && event.eventName !== "hermes.tool.progress") {
27044
27614
  return null;
27045
27615
  }
27046
- const toolName = readString19(event.payload, "tool_name") ?? readString19(event.payload, "tool") ?? readString19(event.payload, "name");
27616
+ const toolName = readString20(event.payload, "tool_name") ?? readString20(event.payload, "tool") ?? readString20(event.payload, "name");
27047
27617
  if (toolName !== "_thinking") {
27048
27618
  return null;
27049
27619
  }
@@ -27094,7 +27664,7 @@ function normalizeHermesResponseEvent(event) {
27094
27664
  }
27095
27665
  function normalizeResponseCreated(event) {
27096
27666
  const response = toRecord18(event.payload.response ?? event.payload);
27097
- const responseId = readString19(response, "id") ?? readString19(event.payload, "id");
27667
+ const responseId = readString20(response, "id") ?? readString20(event.payload, "id");
27098
27668
  return responseId ? {
27099
27669
  ...event,
27100
27670
  payloadType: "response.created",
@@ -27107,10 +27677,10 @@ function normalizeResponseCreated(event) {
27107
27677
  }
27108
27678
  function normalizeResponseOutputItemAdded(event) {
27109
27679
  const item = toRecord18(event.payload.item);
27110
- if (readString19(item, "type") !== "function_call") {
27680
+ if (readString20(item, "type") !== "function_call") {
27111
27681
  return null;
27112
27682
  }
27113
- const toolName = readString19(item, "name") ?? "tool";
27683
+ const toolName = readString20(item, "name") ?? "tool";
27114
27684
  const argumentsValue = parseJsonValue3(item.arguments) ?? item.arguments;
27115
27685
  return {
27116
27686
  ...event,
@@ -27120,16 +27690,16 @@ function normalizeResponseOutputItemAdded(event) {
27120
27690
  tool: toolName,
27121
27691
  tool_name: toolName,
27122
27692
  name: toolName,
27123
- tool_call_id: readString19(item, "call_id") ?? readString19(item, "id"),
27693
+ tool_call_id: readString20(item, "call_id") ?? readString20(item, "id"),
27124
27694
  arguments: argumentsValue,
27125
27695
  preview: toolName,
27126
- response_item_id: readString19(item, "id") ?? void 0
27696
+ response_item_id: readString20(item, "id") ?? void 0
27127
27697
  }
27128
27698
  };
27129
27699
  }
27130
27700
  function normalizeResponseOutputItemDone(event) {
27131
27701
  const item = toRecord18(event.payload.item);
27132
- if (readString19(item, "type") === "message") {
27702
+ if (readString20(item, "type") === "message") {
27133
27703
  const delta = extractResponseAssistantText({ output: [item] });
27134
27704
  return delta ? {
27135
27705
  ...event,
@@ -27137,7 +27707,7 @@ function normalizeResponseOutputItemDone(event) {
27137
27707
  payload: { type: "message.delta", delta }
27138
27708
  } : null;
27139
27709
  }
27140
- if (readString19(item, "type") !== "function_call_output") {
27710
+ if (readString20(item, "type") !== "function_call_output") {
27141
27711
  return null;
27142
27712
  }
27143
27713
  const output = readResponseItemOutput(item.output);
@@ -27147,12 +27717,12 @@ function normalizeResponseOutputItemDone(event) {
27147
27717
  payloadType: "tool.completed",
27148
27718
  payload: {
27149
27719
  type: "tool.completed",
27150
- tool_call_id: readString19(item, "call_id") ?? readString19(item, "id"),
27151
- status: readString19(item, "status") ?? "completed",
27720
+ tool_call_id: readString20(item, "call_id") ?? readString20(item, "id"),
27721
+ status: readString20(item, "status") ?? "completed",
27152
27722
  output,
27153
27723
  content: output,
27154
27724
  result: parsedOutput ?? output,
27155
- response_item_id: readString19(item, "id") ?? void 0
27725
+ response_item_id: readString20(item, "id") ?? void 0
27156
27726
  }
27157
27727
  };
27158
27728
  }
@@ -27163,7 +27733,7 @@ function normalizeResponseCompleted(event) {
27163
27733
  payloadType: "run.completed",
27164
27734
  payload: {
27165
27735
  type: "run.completed",
27166
- response_id: readString19(response, "id") ?? readString19(event.payload, "id"),
27736
+ response_id: readString20(response, "id") ?? readString20(event.payload, "id"),
27167
27737
  usage: toRecord18(response.usage),
27168
27738
  response
27169
27739
  }
@@ -27177,9 +27747,9 @@ function normalizeResponseFailed(event) {
27177
27747
  payloadType: "run.failed",
27178
27748
  payload: {
27179
27749
  type: "run.failed",
27180
- response_id: readString19(response, "id") ?? readString19(event.payload, "id"),
27750
+ response_id: readString20(response, "id") ?? readString20(event.payload, "id"),
27181
27751
  error: {
27182
- message: readString19(error, "message") ?? readString19(event.payload, "message") ?? "Hermes run failed"
27752
+ message: readString20(error, "message") ?? readString20(event.payload, "message") ?? "Hermes run failed"
27183
27753
  },
27184
27754
  usage: toRecord18(response.usage),
27185
27755
  response
@@ -27206,7 +27776,7 @@ function readErrorMessage4(payload) {
27206
27776
  return payload.error.trim();
27207
27777
  }
27208
27778
  const error = toRecord18(payload.error);
27209
- return readString19(error, "message") ?? readString19(payload, "message");
27779
+ return readString20(error, "message") ?? readString20(payload, "message");
27210
27780
  }
27211
27781
  function readDelta(payload) {
27212
27782
  return readText3(payload, "delta") ?? readText3(payload, "text") ?? readText3(payload, "content");
@@ -27253,7 +27823,7 @@ function readChatCompletionDelta(payload) {
27253
27823
  }
27254
27824
  function readChatCompletionFinishReason(payload) {
27255
27825
  const choice = readFirstChoice(payload);
27256
- return readString19(choice, "finish_reason") ?? readString19(choice, "finishReason");
27826
+ return readString20(choice, "finish_reason") ?? readString20(choice, "finishReason");
27257
27827
  }
27258
27828
  function readChatCompletionUsage(payload) {
27259
27829
  const usage = toRecord18(payload.usage);
@@ -27293,7 +27863,7 @@ function readAssistantTextFromChoices(payload) {
27293
27863
  return null;
27294
27864
  }
27295
27865
  const messages2 = choices.map(toRecord18).map((choice) => toRecord18(choice.message ?? choice.delta)).filter((message) => {
27296
- const role = readString19(message, "role");
27866
+ const role = readString20(message, "role");
27297
27867
  return !role || role === "assistant";
27298
27868
  }).map(readResponseMessageText).filter((text) => Boolean(text?.trim()));
27299
27869
  return messages2.length > 0 ? messages2.join("\n\n") : null;
@@ -27309,7 +27879,7 @@ function readInteger3(payload, key) {
27309
27879
  }
27310
27880
  return void 0;
27311
27881
  }
27312
- function readString19(payload, key) {
27882
+ function readString20(payload, key) {
27313
27883
  const value = payload[key];
27314
27884
  return typeof value === "string" && value.trim() ? value.trim() : null;
27315
27885
  }
@@ -27322,8 +27892,8 @@ function readResponseOutputItemText(value) {
27322
27892
  return value;
27323
27893
  }
27324
27894
  const item = toRecord18(value);
27325
- const type = readString19(item, "type");
27326
- const role = readString19(item, "role");
27895
+ const type = readString20(item, "type");
27896
+ const role = readString20(item, "role");
27327
27897
  if (type && type !== "message" && type !== "output_text" && type !== "text") {
27328
27898
  return null;
27329
27899
  }
@@ -27349,7 +27919,7 @@ function readResponseContentText(value) {
27349
27919
  return partValue;
27350
27920
  }
27351
27921
  const part = toRecord18(partValue);
27352
- const type = readString19(part, "type");
27922
+ const type = readString20(part, "type");
27353
27923
  if (type && !isVisibleResponseTextPart(type)) {
27354
27924
  return null;
27355
27925
  }
@@ -27658,6 +28228,11 @@ var ConversationRunLifecycle = class {
27658
28228
  run.profile ?? "default"
27659
28229
  );
27660
28230
  const reasoningEffort = reasoningEffortForRun(run);
28231
+ await this.recordRunHermesMessageWatermark({
28232
+ conversationId,
28233
+ runId,
28234
+ phase: "before"
28235
+ });
27661
28236
  if (backend === "tui_gateway") {
27662
28237
  const rpcRun = await streamTuiGatewayRun({
27663
28238
  input: resolvedInput,
@@ -27873,13 +28448,7 @@ var ConversationRunLifecycle = class {
27873
28448
  }
27874
28449
  } catch (error) {
27875
28450
  if (controller.signal.aborted) {
27876
- await this.deps.withConversationLock(
27877
- conversationId,
27878
- () => this.cancelRunLocked(conversationId, runId, {
27879
- abortUpstream: false,
27880
- reason: "cancelled by app"
27881
- })
27882
- );
28451
+ await this.cancelRunAfterAbort(conversationId, runId);
27883
28452
  return { shouldDrainQueue: true };
27884
28453
  }
27885
28454
  if (isTuiGatewaySessionBusyError(error)) {
@@ -28080,16 +28649,27 @@ var ConversationRunLifecycle = class {
28080
28649
  }
28081
28650
  }
28082
28651
  async cancelRun(conversationId, runId, options) {
28083
- return this.deps.withConversationLock(
28652
+ const result = await this.deps.withConversationLock(
28084
28653
  conversationId,
28085
28654
  () => this.cancelRunLocked(conversationId, runId, options)
28086
28655
  );
28656
+ await this.recordRunHermesMessageWatermark({
28657
+ conversationId,
28658
+ runId,
28659
+ phase: "after"
28660
+ });
28661
+ return result;
28087
28662
  }
28088
28663
  async failRun(conversationId, runId, message, source) {
28089
28664
  await this.refreshRunHermesCompressionTip(conversationId, runId);
28665
+ const afterWatermark = await this.readRunHermesMessageWatermark(
28666
+ conversationId,
28667
+ runId,
28668
+ "after"
28669
+ );
28090
28670
  return this.deps.withConversationLock(
28091
28671
  conversationId,
28092
- () => this.failRunLocked(conversationId, runId, message, source)
28672
+ () => this.failRunLocked(conversationId, runId, message, source, afterWatermark)
28093
28673
  );
28094
28674
  }
28095
28675
  async findConversationIdForRun(runId) {
@@ -28530,6 +29110,11 @@ var ConversationRunLifecycle = class {
28530
29110
  reason: "cancelled by app"
28531
29111
  })
28532
29112
  );
29113
+ await this.recordRunHermesMessageWatermark({
29114
+ conversationId,
29115
+ runId,
29116
+ phase: "after"
29117
+ });
28533
29118
  }
28534
29119
  async completeCancelledRun(conversationId, runId) {
28535
29120
  await this.deps.withConversationLock(
@@ -28539,6 +29124,11 @@ var ConversationRunLifecycle = class {
28539
29124
  reason: "cancelled by Hermes"
28540
29125
  })
28541
29126
  );
29127
+ await this.recordRunHermesMessageWatermark({
29128
+ conversationId,
29129
+ runId,
29130
+ phase: "after"
29131
+ });
28542
29132
  }
28543
29133
  async recoverRunTerminalEvent(input) {
28544
29134
  const deadline = Date.now() + RUN_STATUS_RECOVERY_TIMEOUT_MS;
@@ -28721,14 +29311,14 @@ var ConversationRunLifecycle = class {
28721
29311
  (message) => message.id === input.run.trigger_message_id
28722
29312
  );
28723
29313
  const prefix = guidedInterruptInputPrefix(input.run);
28724
- if (!userMessage || !userMessage.parts.some(isVoicePart)) {
29314
+ if (!userMessage || !userMessage.parts.some(isVoicePart2)) {
28725
29315
  return prefix ? `${prefix}
28726
29316
 
28727
29317
  ${input.fallbackInput}` : input.fallbackInput;
28728
29318
  }
28729
29319
  const content = messageText2(userMessage);
28730
29320
  const voiceLines = [];
28731
- for (const part of userMessage.parts.filter(isVoicePart)) {
29321
+ for (const part of userMessage.parts.filter(isVoicePart2)) {
28732
29322
  const audioPath = part.local_path ?? (part.blob ? blobPath(this.deps.paths, part.blob) : "");
28733
29323
  const result = await transcribeAudioWithHermesProfile({
28734
29324
  audioPath,
@@ -28738,7 +29328,7 @@ ${input.fallbackInput}` : input.fallbackInput;
28738
29328
  const label = part.filename ?? part.blob ?? "voice message";
28739
29329
  voiceLines.push(`- ${label}: ${result.transcript}`);
28740
29330
  }
28741
- const attachmentLines = userMessage.parts.filter((part) => Boolean(part.blob)).filter((part) => !isVoicePart(part)).map((part) => {
29331
+ const attachmentLines = userMessage.parts.filter((part) => Boolean(part.blob)).filter((part) => !isVoicePart2(part)).map((part) => {
28742
29332
  const label = part.filename ?? part.blob;
28743
29333
  const mime = part.mime ? `, ${part.mime}` : "";
28744
29334
  const size = part.size ? `, ${part.size} bytes` : "";
@@ -28824,6 +29414,47 @@ ${resolved}` : resolved;
28824
29414
  Object.assign(run, patch);
28825
29415
  await this.deps.writeSnapshot(conversationId, snapshot);
28826
29416
  }
29417
+ async recordRunHermesMessageWatermark(input) {
29418
+ const point = await this.readRunHermesMessageWatermark(
29419
+ input.conversationId,
29420
+ input.runId,
29421
+ input.phase
29422
+ );
29423
+ if (!point) {
29424
+ return;
29425
+ }
29426
+ await this.deps.withConversationLock(input.conversationId, async () => {
29427
+ const snapshot = await this.deps.readSnapshot(input.conversationId);
29428
+ const run = snapshot.runs.find((item) => item.id === input.runId);
29429
+ if (!run) {
29430
+ return;
29431
+ }
29432
+ applyRunHermesMessageWatermark(run, input.phase, point);
29433
+ await this.deps.writeSnapshot(input.conversationId, snapshot);
29434
+ });
29435
+ }
29436
+ async readRunHermesMessageWatermark(conversationId, runId, phase) {
29437
+ const snapshot = await this.deps.readSnapshot(conversationId).catch(() => null);
29438
+ const run = snapshot?.runs.find((item) => item.id === runId);
29439
+ const sessionId = run?.hermes_session_id?.trim();
29440
+ if (!run || !sessionId) {
29441
+ return null;
29442
+ }
29443
+ return await readHermesMessageWatermark({
29444
+ profileName: run.profile,
29445
+ sessionId
29446
+ }).catch((error) => {
29447
+ void this.deps.logger.debug("hermes_message_watermark_read_failed", {
29448
+ conversation_id: conversationId,
29449
+ run_id: runId,
29450
+ phase,
29451
+ profile: run.profile ?? "default",
29452
+ hermes_session_id: sessionId,
29453
+ error: error instanceof Error ? error.message : String(error)
29454
+ });
29455
+ return null;
29456
+ });
29457
+ }
28827
29458
  async updateRunUsageFromEvent(conversationId, runId, event) {
28828
29459
  const usage = readUsage(event.payload);
28829
29460
  if (!usage) {
@@ -29217,10 +29848,10 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
29217
29848
  return goalStatus;
29218
29849
  }
29219
29850
  async persistGoalStatusUpdate(conversationId, runId, event) {
29220
- if (readString20(event.payload, "kind") !== "goal") {
29851
+ if (readString21(event.payload, "kind") !== "goal") {
29221
29852
  return null;
29222
29853
  }
29223
- const text = readString20(event.payload, "text") ?? readString20(event.payload, "message") ?? readString20(event.payload, "status") ?? "";
29854
+ const text = readString21(event.payload, "text") ?? readString21(event.payload, "message") ?? readString21(event.payload, "status") ?? "";
29224
29855
  const manifest = await this.deps.readRunnableManifest(conversationId);
29225
29856
  const snapshot = await this.deps.readSnapshot(conversationId);
29226
29857
  const run = snapshot.runs.find((item) => item.id === runId);
@@ -29407,7 +30038,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
29407
30038
  }
29408
30039
  const textPart = assistant.parts.find((part) => part.type === "text");
29409
30040
  const currentText = textPart?.text ?? "";
29410
- const pendingDeliveryText = readString20(
30041
+ const pendingDeliveryText = readString21(
29411
30042
  toRecord19(assistant.hermes),
29412
30043
  "pending_media_delivery_text"
29413
30044
  );
@@ -29513,7 +30144,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
29513
30144
  }
29514
30145
  reasoningDeltaSegmentId(event) {
29515
30146
  const payload = event.payload;
29516
- return readString20(payload, "segment_id") ?? readString20(payload, "segmentId") ?? readString20(payload, "id") ?? readString20(payload, "tool_call_id") ?? readString20(payload, "tool_id") ?? null;
30147
+ return readString21(payload, "segment_id") ?? readString21(payload, "segmentId") ?? readString21(payload, "id") ?? readString21(payload, "tool_call_id") ?? readString21(payload, "tool_id") ?? null;
29517
30148
  }
29518
30149
  async runRequestsAppDelivery(conversationId, runId) {
29519
30150
  const snapshot = await this.deps.readSnapshot(conversationId).catch(() => null);
@@ -29525,9 +30156,14 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
29525
30156
  }
29526
30157
  async completeRun(conversationId, runId, source) {
29527
30158
  await this.refreshRunHermesCompressionTip(conversationId, runId);
30159
+ const afterWatermark = await this.readRunHermesMessageWatermark(
30160
+ conversationId,
30161
+ runId,
30162
+ "after"
30163
+ );
29528
30164
  return this.deps.withConversationLock(
29529
30165
  conversationId,
29530
- () => this.completeRunLocked(conversationId, runId, source)
30166
+ () => this.completeRunLocked(conversationId, runId, source, afterWatermark)
29531
30167
  );
29532
30168
  }
29533
30169
  async refreshRunHermesCompressionTip(conversationId, runId) {
@@ -29564,7 +30200,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
29564
30200
  await this.rememberRunHermesSessionId(conversationId, runId, compressionTip);
29565
30201
  return { previousSessionId, nextSessionId: compressionTip };
29566
30202
  }
29567
- async completeRunLocked(conversationId, runId, source) {
30203
+ async completeRunLocked(conversationId, runId, source, afterWatermark) {
29568
30204
  let snapshot = await this.deps.readSnapshot(conversationId);
29569
30205
  let run = snapshot.runs.find((item) => item.id === runId);
29570
30206
  if (!run || run.status !== "running") {
@@ -29606,6 +30242,9 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
29606
30242
  if (usage) {
29607
30243
  run.usage = mergeRunUsage(run.usage, usage);
29608
30244
  }
30245
+ if (afterWatermark) {
30246
+ applyRunHermesMessageWatermark(run, "after", afterWatermark);
30247
+ }
29609
30248
  const probeEvent = shouldUseHermesUsageProbe(run.hermes_backend) ? await findHermesUsageProbeEventForRun({
29610
30249
  paths: this.deps.paths,
29611
30250
  profileName: run.profile,
@@ -29754,7 +30393,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
29754
30393
  await this.deps.writeManifest(nextManifest);
29755
30394
  return goal;
29756
30395
  }
29757
- async failRunLocked(conversationId, runId, message, source) {
30396
+ async failRunLocked(conversationId, runId, message, source, afterWatermark) {
29758
30397
  const snapshot = await this.deps.readSnapshot(conversationId).catch(() => null);
29759
30398
  if (!snapshot) {
29760
30399
  return;
@@ -29777,6 +30416,9 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
29777
30416
  if (usage) {
29778
30417
  run.usage = mergeRunUsage(run.usage, usage);
29779
30418
  }
30419
+ if (afterWatermark) {
30420
+ applyRunHermesMessageWatermark(run, "after", afterWatermark);
30421
+ }
29780
30422
  const assistant = snapshot.messages.find(
29781
30423
  (item) => item.id === run.assistant_message_id
29782
30424
  );
@@ -30140,7 +30782,7 @@ ${details.join("\n")}` : localizedEmptyHermesResponseMessage(language);
30140
30782
  includeDisabled: true
30141
30783
  });
30142
30784
  return new Set(
30143
- jobs.map((job) => readString20(job, "id") ?? readString20(job, "job_id")).filter((id) => Boolean(id))
30785
+ jobs.map((job) => readString21(job, "id") ?? readString21(job, "job_id")).filter((id) => Boolean(id))
30144
30786
  );
30145
30787
  }
30146
30788
  async bindNewCronJobsCreatedByRun(input) {
@@ -30240,7 +30882,7 @@ async function readdirWithDirs(directory) {
30240
30882
  throw error;
30241
30883
  });
30242
30884
  }
30243
- function readString20(payload, key) {
30885
+ function readString21(payload, key) {
30244
30886
  const value = payload[key];
30245
30887
  return typeof value === "string" && value.trim() ? value.trim() : null;
30246
30888
  }
@@ -30331,11 +30973,11 @@ function contextCompressionGeneration(message) {
30331
30973
  return typeof generation === "number" && Number.isFinite(generation) ? Math.max(0, Math.floor(generation)) : null;
30332
30974
  }
30333
30975
  function readPreviousSessionId(payload) {
30334
- return readString20(payload, "old_session_id") ?? readString20(payload, "oldSessionId") ?? readString20(payload, "previous_session_id") ?? readString20(payload, "previousSessionId");
30976
+ return readString21(payload, "old_session_id") ?? readString21(payload, "oldSessionId") ?? readString21(payload, "previous_session_id") ?? readString21(payload, "previousSessionId");
30335
30977
  }
30336
30978
  function readNextSessionId(payload) {
30337
30979
  const info = toRecord19(payload.info);
30338
- return readString20(payload, "session_key") ?? readString20(payload, "sessionKey") ?? readString20(payload, "stored_session_id") ?? readString20(payload, "storedSessionId") ?? readString20(payload, "session_id") ?? readString20(payload, "sessionId") ?? readString20(info, "session_key") ?? readString20(info, "sessionKey");
30980
+ return readString21(payload, "session_key") ?? readString21(payload, "sessionKey") ?? readString21(payload, "stored_session_id") ?? readString21(payload, "storedSessionId") ?? readString21(payload, "session_id") ?? readString21(payload, "sessionId") ?? readString21(info, "session_key") ?? readString21(info, "sessionKey");
30339
30981
  }
30340
30982
  function eventPayloadWithLanguage(payload, language) {
30341
30983
  return { ...payload, language };
@@ -30427,13 +31069,13 @@ function isFileSearchCompletion(payloadType, payload) {
30427
31069
  const toolCall = toRecord19(payload.tool_call ?? payload.toolCall);
30428
31070
  const fn = toRecord19(toolCall.function ?? payload.function);
30429
31071
  const candidates = [
30430
- readString20(payload, "tool_name"),
30431
- readString20(payload, "toolName"),
30432
- readString20(payload, "name"),
30433
- readString20(payload, "tool"),
30434
- readString20(tool, "name"),
30435
- readString20(toolCall, "name"),
30436
- readString20(fn, "name")
31072
+ readString21(payload, "tool_name"),
31073
+ readString21(payload, "toolName"),
31074
+ readString21(payload, "name"),
31075
+ readString21(payload, "tool"),
31076
+ readString21(tool, "name"),
31077
+ readString21(toolCall, "name"),
31078
+ readString21(fn, "name")
30437
31079
  ].filter((value) => Boolean(value)).map(normalizeToolName);
30438
31080
  return candidates.some(
30439
31081
  (name) => [
@@ -30470,7 +31112,7 @@ function messageRequestsAppDelivery(text) {
30470
31112
  const hasEnglishDeliveryAction = /\b(send|share|attach|deliver|display)\b/u.test(lower) || /\bshow\s+me\b/u.test(lower);
30471
31113
  return hasEnglishDeliverable && hasEnglishDeliveryAction;
30472
31114
  }
30473
- function isVoicePart(part) {
31115
+ function isVoicePart2(part) {
30474
31116
  return part.kind === "voice" || part.is_voice_note === true;
30475
31117
  }
30476
31118
  function normalizeToolName(value) {
@@ -30773,13 +31415,13 @@ function readResponseId(payload) {
30773
31415
  return null;
30774
31416
  }
30775
31417
  const response = toRecord19(payload.response);
30776
- return readString20(payload, "response_id") ?? readString20(response, "id");
31418
+ return readString21(payload, "response_id") ?? readString21(response, "id");
30777
31419
  }
30778
31420
  function readRunId(payload) {
30779
31421
  if (!payload) {
30780
31422
  return null;
30781
31423
  }
30782
- return readString20(payload, "run_id") ?? readString20(payload, "runId");
31424
+ return readString21(payload, "run_id") ?? readString21(payload, "runId");
30783
31425
  }
30784
31426
  function isCompletedRunStatus(status) {
30785
31427
  return status === "completed" || status === "complete" || status === "succeeded" || status === "success" || status === "done";
@@ -30798,7 +31440,7 @@ function readStatusErrorMessage(value) {
30798
31440
  return value.trim();
30799
31441
  }
30800
31442
  const record = toRecord19(value);
30801
- return readString20(record, "message") ?? readString20(record, "error");
31443
+ return readString21(record, "message") ?? readString21(record, "error");
30802
31444
  }
30803
31445
  function formatUnknownErrorMessage(error) {
30804
31446
  return error instanceof Error ? error.message : String(error);
@@ -30837,6 +31479,12 @@ function sanitizeLiveSessionForEvent(liveSession) {
30837
31479
  ...liveSession.inflight ? { inflight: liveSession.inflight } : {}
30838
31480
  };
30839
31481
  }
31482
+ function applyRunHermesMessageWatermark(run, phase, point) {
31483
+ run.hermes_message_watermark = {
31484
+ ...run.hermes_message_watermark ?? {},
31485
+ [phase]: point
31486
+ };
31487
+ }
30840
31488
  function previewText2(message) {
30841
31489
  if (!message) {
30842
31490
  return null;
@@ -31686,7 +32334,7 @@ var ConversationService = class {
31686
32334
  );
31687
32335
  }
31688
32336
  const shouldApplyModelConfig = configuredModel != null && !runtimeMatchesConfiguredModel(currentRuntime, configuredModel);
31689
- const modelConfigToApply = shouldApplyModelConfig ? configuredModel : void 0;
32337
+ const modelConfigToApply = configuredModel ?? void 0;
31690
32338
  const sessionConfig = await setTuiGatewaySessionModelConfig({
31691
32339
  hermesSessionId: manifest.hermes_session_id,
31692
32340
  profileName: currentRuntime.profile.name,
@@ -32561,7 +33209,7 @@ var ConversationService = class {
32561
33209
  }
32562
33210
  }
32563
33211
  hermesArchiveStateSyncMarkerPath() {
32564
- return path27.join(this.paths.indexesDir, "hermes-archive-state-sync.json");
33212
+ return path28.join(this.paths.indexesDir, "hermes-archive-state-sync.json");
32565
33213
  }
32566
33214
  prepareClearAllConversationPlan(targetStatus) {
32567
33215
  return this.maintenance.prepareClearAllConversationPlan(targetStatus);
@@ -32843,7 +33491,7 @@ function liveActivityTodoProgressForEvent(event) {
32843
33491
  if (todos) {
32844
33492
  const totalCount2 = todos.length;
32845
33493
  const doneCount2 = todos.filter((item) => {
32846
- const status = readString21(item, "status")?.toLowerCase();
33494
+ const status = readString22(item, "status")?.toLowerCase();
32847
33495
  return status === "completed" || status === "cancelled" || status === "canceled";
32848
33496
  }).length;
32849
33497
  return {
@@ -32892,11 +33540,11 @@ function liveActivityTitleFromConversationUpdate(event) {
32892
33540
  if (event.type.toLowerCase() !== "conversation.updated") {
32893
33541
  return void 0;
32894
33542
  }
32895
- const titleSource = readString21(event.payload, "title_source");
33543
+ const titleSource = readString22(event.payload, "title_source");
32896
33544
  if (titleSource === "default" || titleSource === "temporary_fallback") {
32897
33545
  return null;
32898
33546
  }
32899
- const title = readString21(event.payload, "title");
33547
+ const title = readString22(event.payload, "title");
32900
33548
  return title ? truncateLiveActivityTitle(title, 24) : null;
32901
33549
  }
32902
33550
  function liveActivityTitleFromManifest(manifest) {
@@ -32936,7 +33584,7 @@ function isConversationTitleUpdateEvent(event) {
32936
33584
  if (event.type.toLowerCase() !== "conversation.updated") {
32937
33585
  return false;
32938
33586
  }
32939
- return Boolean(readString21(event.payload, "title")?.trim());
33587
+ return Boolean(readString22(event.payload, "title")?.trim());
32940
33588
  }
32941
33589
  function resolveLiveActivityTarget(input) {
32942
33590
  if (input.run?.kind === "compression") {
@@ -32958,7 +33606,7 @@ function liveActivityPhaseForEvent(event, run, contextOperation) {
32958
33606
  }
32959
33607
  if (type === "conversation.goal.updated") {
32960
33608
  const goal = readRecord2(event.payload).goal;
32961
- const status = readString21(goal, "status");
33609
+ const status = readString22(goal, "status");
32962
33610
  return status === "paused" ? "goal_paused" : "goal_running";
32963
33611
  }
32964
33612
  if (isConversationTitleUpdateEvent(event)) {
@@ -33091,7 +33739,7 @@ function readContextCompressionOperation(payload) {
33091
33739
  if (!operation || typeof operation !== "object") {
33092
33740
  return null;
33093
33741
  }
33094
- const operationId = readString21(operation, "operation_id");
33742
+ const operationId = readString22(operation, "operation_id");
33095
33743
  if (!operationId) {
33096
33744
  return null;
33097
33745
  }
@@ -33099,19 +33747,19 @@ function readContextCompressionOperation(payload) {
33099
33747
  return {
33100
33748
  operation_id: operationId,
33101
33749
  generation: typeof record.generation === "number" ? record.generation : 0,
33102
- status: readString21(record, "status") === "completed" ? "completed" : readString21(record, "status") === "failed" ? "failed" : readString21(record, "status") === "timed_out" ? "timed_out" : readString21(record, "status") === "cancelled" ? "cancelled" : "compressing",
33103
- started_at: readString21(record, "started_at") ?? (/* @__PURE__ */ new Date()).toISOString(),
33104
- source: readString21(record, "source") === "manual" ? "manual" : "auto"
33750
+ status: readString22(record, "status") === "completed" ? "completed" : readString22(record, "status") === "failed" ? "failed" : readString22(record, "status") === "timed_out" ? "timed_out" : readString22(record, "status") === "cancelled" ? "cancelled" : "compressing",
33751
+ started_at: readString22(record, "started_at") ?? (/* @__PURE__ */ new Date()).toISOString(),
33752
+ source: readString22(record, "source") === "manual" ? "manual" : "auto"
33105
33753
  };
33106
33754
  }
33107
33755
  function readToolName3(payload) {
33108
33756
  const record = readRecord2(payload);
33109
- return readString21(record, "tool_name") ?? readString21(record, "tool") ?? readString21(record, "name") ?? readString21(readRecord2(record.tool), "name");
33757
+ return readString22(record, "tool_name") ?? readString22(record, "tool") ?? readString22(record, "name") ?? readString22(readRecord2(record.tool), "name");
33110
33758
  }
33111
33759
  function readRecord2(value) {
33112
33760
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
33113
33761
  }
33114
- function readString21(value, key) {
33762
+ function readString22(value, key) {
33115
33763
  const raw = readRecord2(value)[key];
33116
33764
  return typeof raw === "string" && raw.trim() ? raw.trim() : null;
33117
33765
  }
@@ -33631,7 +34279,7 @@ async function readRawBody(request, maxBytes) {
33631
34279
  }
33632
34280
  return Buffer.concat(chunks);
33633
34281
  }
33634
- function readString22(body, key) {
34282
+ function readString23(body, key) {
33635
34283
  const value = body[key];
33636
34284
  return typeof value === "string" && value.trim() ? value.trim() : null;
33637
34285
  }
@@ -33666,7 +34314,7 @@ function readSupportedLanguage(value) {
33666
34314
  return null;
33667
34315
  }
33668
34316
  function readOptionalProfileName(body) {
33669
- return readString22(body, "profile") ?? readString22(body, "profile_name") ?? readString22(body, "profileName") ?? void 0;
34317
+ return readString23(body, "profile") ?? readString23(body, "profile_name") ?? readString23(body, "profileName") ?? void 0;
33670
34318
  }
33671
34319
  function readStringArray(body, ...keys) {
33672
34320
  for (const key of keys) {
@@ -34024,7 +34672,8 @@ function registerConversationRoutes(router, options) {
34024
34672
  const result = await conversations.listConversationPage({
34025
34673
  limit: readLimit(ctx.query.limit),
34026
34674
  cursor,
34027
- workspace: readConversationWorkspaceFilter(ctx.query)
34675
+ workspace: readConversationWorkspaceFilter(ctx.query),
34676
+ category: readConversationCategoryFilter(ctx.query)
34028
34677
  });
34029
34678
  const localized = localizeConversationListPage(result, language);
34030
34679
  ctx.body = {
@@ -34086,7 +34735,7 @@ function registerConversationRoutes(router, options) {
34086
34735
  const language = readPreferredLanguage(ctx);
34087
34736
  const body = await readJsonBody(ctx.req);
34088
34737
  ctx.status = 201;
34089
- const rawReasoningEffort = readString22(body, "reasoning_effort") ?? readString22(body, "reasoningEffort") ?? readString22(body, "default_reasoning_effort") ?? readString22(body, "defaultReasoningEffort");
34738
+ const rawReasoningEffort = readString23(body, "reasoning_effort") ?? readString23(body, "reasoningEffort") ?? readString23(body, "default_reasoning_effort") ?? readString23(body, "defaultReasoningEffort");
34090
34739
  const reasoningEffort = normalizeReasoningEffort(rawReasoningEffort);
34091
34740
  if (rawReasoningEffort && !reasoningEffort) {
34092
34741
  throw new LinkHttpError(
@@ -34099,15 +34748,15 @@ function registerConversationRoutes(router, options) {
34099
34748
  ok: true,
34100
34749
  conversation: localizeConversationSummary(
34101
34750
  await conversations.createConversation({
34102
- title: readString22(body, "title") ?? void 0,
34751
+ title: readString23(body, "title") ?? void 0,
34103
34752
  profileName: readOptionalProfileName(body),
34104
34753
  accountId: auth.accountId,
34105
34754
  appInstanceId: auth.appInstanceId,
34106
34755
  workspaceId: readConversationWorkspaceId(body),
34107
- modelId: readString22(body, "model_id") ?? readString22(body, "modelId") ?? readString22(body, "model") ?? void 0,
34108
- modelProvider: readString22(body, "model_provider") ?? readString22(body, "modelProvider") ?? readString22(body, "provider") ?? void 0,
34109
- modelBaseUrl: readString22(body, "model_base_url") ?? readString22(body, "modelBaseUrl") ?? readString22(body, "base_url") ?? readString22(body, "baseUrl") ?? void 0,
34110
- modelApiMode: readString22(body, "model_api_mode") ?? readString22(body, "modelApiMode") ?? readString22(body, "api_mode") ?? readString22(body, "apiMode") ?? void 0,
34756
+ modelId: readString23(body, "model_id") ?? readString23(body, "modelId") ?? readString23(body, "model") ?? void 0,
34757
+ modelProvider: readString23(body, "model_provider") ?? readString23(body, "modelProvider") ?? readString23(body, "provider") ?? void 0,
34758
+ modelBaseUrl: readString23(body, "model_base_url") ?? readString23(body, "modelBaseUrl") ?? readString23(body, "base_url") ?? readString23(body, "baseUrl") ?? void 0,
34759
+ modelApiMode: readString23(body, "model_api_mode") ?? readString23(body, "modelApiMode") ?? readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? void 0,
34111
34760
  reasoningEffort
34112
34761
  }),
34113
34762
  language
@@ -34185,9 +34834,9 @@ function registerConversationRoutes(router, options) {
34185
34834
  const auth = await authenticateRequest(ctx, paths);
34186
34835
  const language = readPreferredLanguage(ctx);
34187
34836
  const body = await readJsonBody(ctx.req);
34188
- const content = readString22(body, "content") ?? readString22(body, "text") ?? readString22(body, "input") ?? "";
34837
+ const content = readString23(body, "content") ?? readString23(body, "text") ?? readString23(body, "input") ?? "";
34189
34838
  const attachments = readMessageAttachments(body.attachments ?? body.blobs);
34190
- const mode = readString22(body, "mode") ?? readString22(body, "send_mode");
34839
+ const mode = readString23(body, "mode") ?? readString23(body, "send_mode");
34191
34840
  if (mode && mode !== "message" && mode !== "goal") {
34192
34841
  throw new LinkHttpError(
34193
34842
  400,
@@ -34210,7 +34859,7 @@ function registerConversationRoutes(router, options) {
34210
34859
  conversationId: ctx.params.conversationId,
34211
34860
  content,
34212
34861
  attachments,
34213
- clientMessageId: readString22(body, "client_message_id") ?? readString22(body, "clientMessageId") ?? void 0,
34862
+ clientMessageId: readString23(body, "client_message_id") ?? readString23(body, "clientMessageId") ?? void 0,
34214
34863
  idempotencyKey: readHeader(ctx, "idempotency-key") ?? void 0,
34215
34864
  profileName: readOptionalProfileName(body),
34216
34865
  mode: mode === "goal" ? "goal" : "message",
@@ -34277,8 +34926,8 @@ function registerConversationRoutes(router, options) {
34277
34926
  ...localizeConversationResult(
34278
34927
  await conversations.startContextCompression({
34279
34928
  conversationId: ctx.params.conversationId,
34280
- focus: readString22(body, "focus") ?? readString22(body, "focus_topic") ?? readString22(body, "focusTopic") ?? void 0,
34281
- clientOperationId: readString22(body, "client_operation_id") ?? readString22(body, "clientOperationId") ?? readHeader(ctx, "idempotency-key") ?? void 0,
34929
+ focus: readString23(body, "focus") ?? readString23(body, "focus_topic") ?? readString23(body, "focusTopic") ?? void 0,
34930
+ clientOperationId: readString23(body, "client_operation_id") ?? readString23(body, "clientOperationId") ?? readHeader(ctx, "idempotency-key") ?? void 0,
34282
34931
  createUserMessage: false,
34283
34932
  accountId: auth.accountId,
34284
34933
  appInstanceId: auth.appInstanceId,
@@ -34292,11 +34941,11 @@ function registerConversationRoutes(router, options) {
34292
34941
  router.patch("/api/v1/conversations/:conversationId/model", async (ctx) => {
34293
34942
  await authenticateRequest(ctx, paths);
34294
34943
  const body = await readJsonBody(ctx.req);
34295
- const modelId = readString22(body, "model_id") ?? readString22(body, "modelId") ?? readString22(body, "model");
34296
- const modelProvider = readString22(body, "model_provider") ?? readString22(body, "modelProvider") ?? readString22(body, "provider") ?? void 0;
34297
- const modelBaseUrl = readString22(body, "model_base_url") ?? readString22(body, "modelBaseUrl") ?? readString22(body, "base_url") ?? readString22(body, "baseUrl") ?? void 0;
34298
- const modelApiMode = readString22(body, "model_api_mode") ?? readString22(body, "modelApiMode") ?? readString22(body, "api_mode") ?? readString22(body, "apiMode") ?? void 0;
34299
- const rawReasoningEffort = readString22(body, "reasoning_effort") ?? readString22(body, "reasoningEffort") ?? readString22(body, "default_reasoning_effort") ?? readString22(body, "defaultReasoningEffort");
34944
+ const modelId = readString23(body, "model_id") ?? readString23(body, "modelId") ?? readString23(body, "model");
34945
+ const modelProvider = readString23(body, "model_provider") ?? readString23(body, "modelProvider") ?? readString23(body, "provider") ?? void 0;
34946
+ const modelBaseUrl = readString23(body, "model_base_url") ?? readString23(body, "modelBaseUrl") ?? readString23(body, "base_url") ?? readString23(body, "baseUrl") ?? void 0;
34947
+ const modelApiMode = readString23(body, "model_api_mode") ?? readString23(body, "modelApiMode") ?? readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? void 0;
34948
+ const rawReasoningEffort = readString23(body, "reasoning_effort") ?? readString23(body, "reasoningEffort") ?? readString23(body, "default_reasoning_effort") ?? readString23(body, "defaultReasoningEffort");
34300
34949
  const reasoningEffort = normalizeReasoningEffort(rawReasoningEffort);
34301
34950
  if (rawReasoningEffort && !reasoningEffort) {
34302
34951
  throw new LinkHttpError(
@@ -34346,7 +34995,7 @@ function registerConversationRoutes(router, options) {
34346
34995
  await authenticateRequest(ctx, paths);
34347
34996
  const language = readPreferredLanguage(ctx);
34348
34997
  const body = await readJsonBody(ctx.req);
34349
- const title = readString22(body, "title") ?? readString22(body, "name") ?? readString22(body, "display_name");
34998
+ const title = readString23(body, "title") ?? readString23(body, "name") ?? readString23(body, "display_name");
34350
34999
  if (!title) {
34351
35000
  throw new LinkHttpError(400, "title_required", "title is required");
34352
35001
  }
@@ -34538,7 +35187,7 @@ function registerConversationRoutes(router, options) {
34538
35187
  async (ctx) => {
34539
35188
  await authenticateRequest(ctx, paths);
34540
35189
  const body = await readJsonBody(ctx.req);
34541
- const scope = readString22(body, "scope") ?? "always";
35190
+ const scope = readString23(body, "scope") ?? "always";
34542
35191
  ctx.body = {
34543
35192
  ok: true,
34544
35193
  ...await conversations.resolveApproval({
@@ -34588,7 +35237,7 @@ function registerConversationRoutes(router, options) {
34588
35237
  conversationId: ctx.params.conversationId,
34589
35238
  requestId: ctx.params.requestId,
34590
35239
  kind,
34591
- answer: readString22(body, "answer") ?? void 0,
35240
+ answer: readString23(body, "answer") ?? void 0,
34592
35241
  password: readRawString(body, "password"),
34593
35242
  value: readRawString(body, "value")
34594
35243
  })
@@ -34755,12 +35404,27 @@ function readConversationWorkspaceFilter(query) {
34755
35404
  }
34756
35405
  return { kind: "workspace", workspaceId: workspace };
34757
35406
  }
35407
+ function readConversationCategoryFilter(query) {
35408
+ const category = readQueryString(query.category) ?? readQueryString(query.conversation_category) ?? readQueryString(query.conversationCategory);
35409
+ const normalized = category?.trim().toLowerCase();
35410
+ if (!normalized || normalized === "all") {
35411
+ return "all";
35412
+ }
35413
+ if (normalized === "chat" || normalized === "cron") {
35414
+ return normalized;
35415
+ }
35416
+ throw new LinkHttpError(
35417
+ 400,
35418
+ "conversation_category_invalid",
35419
+ "conversation category must be all, chat or cron"
35420
+ );
35421
+ }
34758
35422
  function readConversationWorkspaceId(body) {
34759
35423
  if (Object.prototype.hasOwnProperty.call(body, "workspace_id") || Object.prototype.hasOwnProperty.call(body, "workspaceId")) {
34760
- return readString22(body, "workspace_id") ?? readString22(body, "workspaceId");
35424
+ return readString23(body, "workspace_id") ?? readString23(body, "workspaceId");
34761
35425
  }
34762
35426
  if (Object.prototype.hasOwnProperty.call(body, "workspace")) {
34763
- return readString22(body, "workspace");
35427
+ return readString23(body, "workspace");
34764
35428
  }
34765
35429
  return void 0;
34766
35430
  }
@@ -34854,7 +35518,7 @@ function resolveConversationEventCursor(input) {
34854
35518
  return Math.max(queryAfter, headerAfter);
34855
35519
  }
34856
35520
  function readConversationClearPlanTargetStatus(body) {
34857
- const raw = readString22(body, "target_status") ?? readString22(body, "targetStatus") ?? "active";
35521
+ const raw = readString23(body, "target_status") ?? readString23(body, "targetStatus") ?? "active";
34858
35522
  if (raw === "active" || raw === "archived") {
34859
35523
  return raw;
34860
35524
  }
@@ -34865,7 +35529,7 @@ function readConversationClearPlanTargetStatus(body) {
34865
35529
  );
34866
35530
  }
34867
35531
  function readInputRequestKind2(body) {
34868
- const kind = readString22(body, "kind") ?? readString22(body, "type");
35532
+ const kind = readString23(body, "kind") ?? readString23(body, "type");
34869
35533
  if (kind === "clarify" || kind === "sudo" || kind === "secret") {
34870
35534
  return kind;
34871
35535
  }
@@ -34995,11 +35659,11 @@ function isSseRequestContext(ctx) {
34995
35659
  }
34996
35660
  return isSseRequestPath(ctx.path) || isActiveSseSocket(ctx.req.socket);
34997
35661
  }
34998
- function isSseRequestPath(path38) {
34999
- if (!path38) {
35662
+ function isSseRequestPath(path39) {
35663
+ if (!path39) {
35000
35664
  return false;
35001
35665
  }
35002
- return path38 === "/api/v1/conversations/events" || path38 === "/api/v1/profile-creation/events" || path38 === "/api/v1/hermes/update/events" || path38 === "/api/v1/link/update/events" || /^\/api\/v1\/conversations\/[^/]+\/events$/u.test(path38) || /^\/api\/v1\/runs\/[^/]+\/events$/u.test(path38);
35666
+ return path39 === "/api/v1/conversations/events" || path39 === "/api/v1/profile-creation/events" || path39 === "/api/v1/hermes/update/events" || path39 === "/api/v1/link/update/events" || /^\/api\/v1\/conversations\/[^/]+\/events$/u.test(path39) || /^\/api\/v1\/runs\/[^/]+\/events$/u.test(path39);
35003
35667
  }
35004
35668
  function isExpectedClientDisconnectError2(error, options = {}) {
35005
35669
  if (!(error instanceof Error)) {
@@ -35263,7 +35927,7 @@ function toHermesCronJobInput(input) {
35263
35927
  };
35264
35928
  }
35265
35929
  async function bindAndDecorateCronJobForHermesLink(input) {
35266
- const jobId = readString22(input.job, "id") ?? readString22(input.job, "job_id");
35930
+ const jobId = readString23(input.job, "id") ?? readString23(input.job, "job_id");
35267
35931
  if (!jobId) {
35268
35932
  return input.job;
35269
35933
  }
@@ -35282,9 +35946,9 @@ async function bindAndDecorateCronJobForHermesLink(input) {
35282
35946
  }
35283
35947
  function readCronJobCreateInput(body) {
35284
35948
  const input = {};
35285
- const name = readString22(body, "name") ?? readString22(body, "title");
35286
- const prompt = readString22(body, "prompt") ?? readString22(body, "description") ?? readString22(body, "task");
35287
- const schedule = readString22(body, "schedule");
35949
+ const name = readString23(body, "name") ?? readString23(body, "title");
35950
+ const prompt = readString23(body, "prompt") ?? readString23(body, "description") ?? readString23(body, "task");
35951
+ const schedule = readString23(body, "schedule");
35288
35952
  if (!name) {
35289
35953
  throw new LinkHttpError(400, "cron_job_name_required", "name is required");
35290
35954
  }
@@ -35305,7 +35969,7 @@ function readCronJobCreateInput(body) {
35305
35969
  input.name = name;
35306
35970
  input.prompt = prompt;
35307
35971
  input.schedule = schedule;
35308
- input.deliver = readString22(body, "deliver") ?? HERMES_LINK_CRON_DELIVER;
35972
+ input.deliver = readString23(body, "deliver") ?? HERMES_LINK_CRON_DELIVER;
35309
35973
  const skills = readOptionalCronSkills(body);
35310
35974
  if (skills) {
35311
35975
  input.skills = skills;
@@ -35438,7 +36102,7 @@ import { createHash as createHash11 } from "crypto";
35438
36102
  // src/model-catalog/catalog.ts
35439
36103
  import { randomInt } from "crypto";
35440
36104
  import { mkdir as mkdir12 } from "fs/promises";
35441
- import path28 from "path";
36105
+ import path29 from "path";
35442
36106
  import { fileURLToPath } from "url";
35443
36107
  var MODEL_CATALOG_CACHE_VERSION = 1;
35444
36108
  var MODEL_CATALOG_FETCH_TIMEOUT_MS = 1e4;
@@ -35642,7 +36306,7 @@ async function readCachedCatalogFile(paths) {
35642
36306
  return cached;
35643
36307
  }
35644
36308
  async function writeCachedCatalog(paths, value) {
35645
- await mkdir12(path28.dirname(modelCatalogCachePath(paths)), {
36309
+ await mkdir12(path29.dirname(modelCatalogCachePath(paths)), {
35646
36310
  recursive: true,
35647
36311
  mode: 448
35648
36312
  });
@@ -35658,7 +36322,7 @@ async function readFallbackCatalog() {
35658
36322
  throw new Error("model capability fallback catalog was not found");
35659
36323
  }
35660
36324
  function modelCatalogCachePath(paths) {
35661
- return path28.join(paths.homeDir, "model-capabilities", "catalog-cache.json");
36325
+ return path29.join(paths.homeDir, "model-capabilities", "catalog-cache.json");
35662
36326
  }
35663
36327
  function normalizeModelCapabilityCatalog(value) {
35664
36328
  if (!value || typeof value !== "object") {
@@ -35669,7 +36333,7 @@ function normalizeModelCapabilityCatalog(value) {
35669
36333
  const models = rawModels.map(normalizeModelCapabilityEntry).filter((entry) => entry !== null);
35670
36334
  return {
35671
36335
  schemaVersion: readPositiveInteger3(record.schemaVersion) ?? 1,
35672
- updatedAt: readString23(record.updatedAt),
36336
+ updatedAt: readString24(record.updatedAt),
35673
36337
  models
35674
36338
  };
35675
36339
  }
@@ -35678,7 +36342,7 @@ function normalizeModelCapabilityEntry(value) {
35678
36342
  return null;
35679
36343
  }
35680
36344
  const record = value;
35681
- const canonicalId = readString23(record.canonicalId) ?? readString23(record.canonical_id) ?? readString23(record.id);
36345
+ const canonicalId = readString24(record.canonicalId) ?? readString24(record.canonical_id) ?? readString24(record.id);
35682
36346
  if (!canonicalId) {
35683
36347
  return null;
35684
36348
  }
@@ -35706,12 +36370,12 @@ function normalizeModelCapabilityEntry(value) {
35706
36370
  outputModalities: readStringArray2(
35707
36371
  record.outputModalities ?? record.output_modalities
35708
36372
  ),
35709
- source: readString23(record.source),
35710
- updatedAt: readString23(record.updatedAt ?? record.updated_at),
35711
- notes: readString23(record.notes)
36373
+ source: readString24(record.source),
36374
+ updatedAt: readString24(record.updatedAt ?? record.updated_at),
36375
+ notes: readString24(record.notes)
35712
36376
  };
35713
36377
  }
35714
- function readString23(value) {
36378
+ function readString24(value) {
35715
36379
  return typeof value === "string" && value.trim() ? value.trim() : null;
35716
36380
  }
35717
36381
  function readStringArray2(value) {
@@ -35721,7 +36385,7 @@ function readStringArray2(value) {
35721
36385
  const seen = /* @__PURE__ */ new Set();
35722
36386
  const values = [];
35723
36387
  for (const item of value) {
35724
- const text = readString23(item);
36388
+ const text = readString24(item);
35725
36389
  if (!text || seen.has(text)) {
35726
36390
  continue;
35727
36391
  }
@@ -35738,7 +36402,7 @@ function readPositiveInteger3(value) {
35738
36402
  return Math.floor(number);
35739
36403
  }
35740
36404
  function readReasoningSupportPolicy(value) {
35741
- const normalized = readString23(value)?.toLowerCase();
36405
+ const normalized = readString24(value)?.toLowerCase();
35742
36406
  if (!normalized || normalized === "unknown" || normalized === "auto") {
35743
36407
  return null;
35744
36408
  }
@@ -35769,7 +36433,7 @@ function readNullableBoolean(value) {
35769
36433
  if (typeof value === "boolean") {
35770
36434
  return value;
35771
36435
  }
35772
- const normalized = readString23(value)?.toLowerCase();
36436
+ const normalized = readString24(value)?.toLowerCase();
35773
36437
  if (!normalized) {
35774
36438
  return null;
35775
36439
  }
@@ -36918,8 +37582,8 @@ function normalizeUrlForIdentity(value) {
36918
37582
  return value.trim().replace(/\/+$/u, "").toLowerCase();
36919
37583
  }
36920
37584
  function readModelProviderConfigInput(body) {
36921
- const providerName = readString22(body, "display_name") ?? readString22(body, "displayName") ?? readString22(body, "provider_name") ?? readString22(body, "providerName") ?? readString22(body, "name");
36922
- const baseUrl = readString22(body, "base_url") ?? readString22(body, "baseUrl");
37585
+ const providerName = readString23(body, "display_name") ?? readString23(body, "displayName") ?? readString23(body, "provider_name") ?? readString23(body, "providerName") ?? readString23(body, "name");
37586
+ const baseUrl = readString23(body, "base_url") ?? readString23(body, "baseUrl");
36923
37587
  if (!providerName || !baseUrl) {
36924
37588
  throw new LinkHttpError(
36925
37589
  400,
@@ -36930,15 +37594,15 @@ function readModelProviderConfigInput(body) {
36930
37594
  return {
36931
37595
  providerName,
36932
37596
  baseUrl,
36933
- apiMode: readString22(body, "api_mode") ?? readString22(body, "apiMode") ?? readString22(body, "transport") ?? void 0,
36934
- keyEnv: readString22(body, "key_env") ?? readString22(body, "keyEnv") ?? void 0,
36935
- apiKey: readString22(body, "api_key") ?? readString22(body, "apiKey") ?? void 0
37597
+ apiMode: readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? readString23(body, "transport") ?? void 0,
37598
+ keyEnv: readString23(body, "key_env") ?? readString23(body, "keyEnv") ?? void 0,
37599
+ apiKey: readString23(body, "api_key") ?? readString23(body, "apiKey") ?? void 0
36936
37600
  };
36937
37601
  }
36938
37602
  function readModelConfigInput(body) {
36939
- const id = readString22(body, "id") ?? readString22(body, "model_id") ?? readString22(body, "modelId");
36940
- const provider = readString22(body, "provider") ?? readString22(body, "provider_key") ?? readString22(body, "providerKey");
36941
- const baseUrl = readString22(body, "base_url") ?? readString22(body, "baseUrl");
37603
+ const id = readString23(body, "id") ?? readString23(body, "model_id") ?? readString23(body, "modelId");
37604
+ const provider = readString23(body, "provider") ?? readString23(body, "provider_key") ?? readString23(body, "providerKey");
37605
+ const baseUrl = readString23(body, "base_url") ?? readString23(body, "baseUrl");
36942
37606
  if (!id || !provider || !baseUrl) {
36943
37607
  throw new LinkHttpError(
36944
37608
  400,
@@ -36948,22 +37612,22 @@ function readModelConfigInput(body) {
36948
37612
  }
36949
37613
  return {
36950
37614
  id,
36951
- originalModelId: readString22(body, "original_model_id") ?? readString22(body, "originalModelId") ?? readString22(body, "original_id") ?? void 0,
36952
- originalProvider: readString22(body, "original_provider") ?? readString22(body, "originalProvider") ?? readString22(body, "original_provider_key") ?? readString22(body, "originalProviderKey") ?? void 0,
36953
- originalBaseUrl: readString22(body, "original_base_url") ?? readString22(body, "originalBaseUrl") ?? void 0,
36954
- originalApiMode: readString22(body, "original_api_mode") ?? readString22(body, "originalApiMode") ?? void 0,
37615
+ originalModelId: readString23(body, "original_model_id") ?? readString23(body, "originalModelId") ?? readString23(body, "original_id") ?? void 0,
37616
+ originalProvider: readString23(body, "original_provider") ?? readString23(body, "originalProvider") ?? readString23(body, "original_provider_key") ?? readString23(body, "originalProviderKey") ?? void 0,
37617
+ originalBaseUrl: readString23(body, "original_base_url") ?? readString23(body, "originalBaseUrl") ?? void 0,
37618
+ originalApiMode: readString23(body, "original_api_mode") ?? readString23(body, "originalApiMode") ?? void 0,
36955
37619
  provider,
36956
- providerName: readString22(body, "provider_name") ?? readString22(body, "providerName") ?? void 0,
37620
+ providerName: readString23(body, "provider_name") ?? readString23(body, "providerName") ?? void 0,
36957
37621
  baseUrl,
36958
- apiKey: readString22(body, "api_key") ?? readString22(body, "apiKey") ?? void 0,
36959
- apiMode: readString22(body, "api_mode") ?? readString22(body, "apiMode") ?? void 0,
37622
+ apiKey: readString23(body, "api_key") ?? readString23(body, "apiKey") ?? void 0,
37623
+ apiMode: readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? void 0,
36960
37624
  contextLength: readPositiveInteger2(
36961
37625
  body.context_length ?? body.contextLength
36962
37626
  ),
36963
- keyEnv: readString22(body, "key_env") ?? readString22(body, "keyEnv") ?? void 0,
37627
+ keyEnv: readString23(body, "key_env") ?? readString23(body, "keyEnv") ?? void 0,
36964
37628
  setDefault: readBoolean4(body.set_default ?? body.setDefault),
36965
- reasoningEffort: readString22(body, "reasoning_effort") ?? readString22(body, "reasoningEffort") ?? void 0,
36966
- reasoningSupportPolicy: readString22(body, "reasoning_support_policy") ?? readString22(body, "reasoningSupportPolicy") ?? readString22(body, "reasoning_support") ?? readString22(body, "reasoningSupport") ?? void 0,
37629
+ reasoningEffort: readString23(body, "reasoning_effort") ?? readString23(body, "reasoningEffort") ?? void 0,
37630
+ reasoningSupportPolicy: readString23(body, "reasoning_support_policy") ?? readString23(body, "reasoningSupportPolicy") ?? readString23(body, "reasoning_support") ?? readString23(body, "reasoningSupport") ?? void 0,
36967
37631
  supportsVision: readNullableBoolean2(
36968
37632
  body.supports_vision ?? body.supportsVision
36969
37633
  )
@@ -36971,28 +37635,28 @@ function readModelConfigInput(body) {
36971
37635
  }
36972
37636
  function readModelDefaultsInput(body) {
36973
37637
  return {
36974
- taskModelId: readString22(body, "task_model_id") ?? readString22(body, "taskModelId") ?? readString22(body, "default_model_id") ?? readString22(body, "defaultModelId") ?? void 0,
36975
- taskModelProvider: readString22(body, "task_model_provider") ?? readString22(body, "taskModelProvider") ?? readString22(body, "default_model_provider") ?? readString22(body, "defaultModelProvider") ?? void 0,
36976
- taskModelBaseUrl: readString22(body, "task_model_base_url") ?? readString22(body, "taskModelBaseUrl") ?? readString22(body, "default_model_base_url") ?? readString22(body, "defaultModelBaseUrl") ?? void 0,
36977
- taskModelApiMode: readString22(body, "task_model_api_mode") ?? readString22(body, "taskModelApiMode") ?? readString22(body, "default_model_api_mode") ?? readString22(body, "defaultModelApiMode") ?? void 0,
36978
- compressionModelId: readString22(body, "compression_model_id") ?? readString22(body, "compressionModelId") ?? void 0,
36979
- compressionModelProvider: readString22(body, "compression_model_provider") ?? readString22(body, "compressionModelProvider") ?? void 0,
36980
- compressionModelBaseUrl: readString22(body, "compression_model_base_url") ?? readString22(body, "compressionModelBaseUrl") ?? void 0,
36981
- compressionModelApiMode: readString22(body, "compression_model_api_mode") ?? readString22(body, "compressionModelApiMode") ?? void 0,
36982
- reasoningEffort: readString22(body, "reasoning_effort") ?? readString22(body, "reasoningEffort") ?? readString22(body, "default_reasoning_effort") ?? readString22(body, "defaultReasoningEffort") ?? void 0,
36983
- imageInputMode: readString22(body, "image_input_mode") ?? readString22(body, "imageInputMode") ?? void 0
37638
+ taskModelId: readString23(body, "task_model_id") ?? readString23(body, "taskModelId") ?? readString23(body, "default_model_id") ?? readString23(body, "defaultModelId") ?? void 0,
37639
+ taskModelProvider: readString23(body, "task_model_provider") ?? readString23(body, "taskModelProvider") ?? readString23(body, "default_model_provider") ?? readString23(body, "defaultModelProvider") ?? void 0,
37640
+ taskModelBaseUrl: readString23(body, "task_model_base_url") ?? readString23(body, "taskModelBaseUrl") ?? readString23(body, "default_model_base_url") ?? readString23(body, "defaultModelBaseUrl") ?? void 0,
37641
+ taskModelApiMode: readString23(body, "task_model_api_mode") ?? readString23(body, "taskModelApiMode") ?? readString23(body, "default_model_api_mode") ?? readString23(body, "defaultModelApiMode") ?? void 0,
37642
+ compressionModelId: readString23(body, "compression_model_id") ?? readString23(body, "compressionModelId") ?? void 0,
37643
+ compressionModelProvider: readString23(body, "compression_model_provider") ?? readString23(body, "compressionModelProvider") ?? void 0,
37644
+ compressionModelBaseUrl: readString23(body, "compression_model_base_url") ?? readString23(body, "compressionModelBaseUrl") ?? void 0,
37645
+ compressionModelApiMode: readString23(body, "compression_model_api_mode") ?? readString23(body, "compressionModelApiMode") ?? void 0,
37646
+ reasoningEffort: readString23(body, "reasoning_effort") ?? readString23(body, "reasoningEffort") ?? readString23(body, "default_reasoning_effort") ?? readString23(body, "defaultReasoningEffort") ?? void 0,
37647
+ imageInputMode: readString23(body, "image_input_mode") ?? readString23(body, "imageInputMode") ?? void 0
36984
37648
  };
36985
37649
  }
36986
37650
  function readModelDeleteInput(body) {
36987
- const id = readString22(body, "model_id") ?? readString22(body, "modelId");
37651
+ const id = readString23(body, "model_id") ?? readString23(body, "modelId");
36988
37652
  if (!id) {
36989
37653
  throw new LinkHttpError(400, "model_id_required", "model_id is required");
36990
37654
  }
36991
37655
  return {
36992
37656
  id,
36993
- provider: readString22(body, "provider") ?? readString22(body, "provider_key") ?? readString22(body, "providerKey") ?? void 0,
36994
- baseUrl: readString22(body, "base_url") ?? readString22(body, "baseUrl") ?? void 0,
36995
- apiMode: readString22(body, "api_mode") ?? readString22(body, "apiMode") ?? void 0
37657
+ provider: readString23(body, "provider") ?? readString23(body, "provider_key") ?? readString23(body, "providerKey") ?? void 0,
37658
+ baseUrl: readString23(body, "base_url") ?? readString23(body, "baseUrl") ?? void 0,
37659
+ apiMode: readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? void 0
36996
37660
  };
36997
37661
  }
36998
37662
  function readNullableBoolean2(value) {
@@ -37015,8 +37679,8 @@ function readNullableBoolean2(value) {
37015
37679
  return void 0;
37016
37680
  }
37017
37681
  function readModelConfigImportInput(body) {
37018
- const sourceProfileName = readString22(body, "source_profile") ?? readString22(body, "sourceProfile") ?? readString22(body, "source_profile_name") ?? readString22(body, "sourceProfileName");
37019
- const modelId = readString22(body, "model_id") ?? readString22(body, "modelId") ?? readString22(body, "id");
37682
+ const sourceProfileName = readString23(body, "source_profile") ?? readString23(body, "sourceProfile") ?? readString23(body, "source_profile_name") ?? readString23(body, "sourceProfileName");
37683
+ const modelId = readString23(body, "model_id") ?? readString23(body, "modelId") ?? readString23(body, "id");
37020
37684
  if (!sourceProfileName || !modelId) {
37021
37685
  throw new LinkHttpError(
37022
37686
  400,
@@ -37027,9 +37691,9 @@ function readModelConfigImportInput(body) {
37027
37691
  return {
37028
37692
  sourceProfileName,
37029
37693
  modelId,
37030
- provider: readString22(body, "provider") ?? readString22(body, "provider_key") ?? readString22(body, "providerKey") ?? void 0,
37031
- baseUrl: readString22(body, "base_url") ?? readString22(body, "baseUrl") ?? void 0,
37032
- apiMode: readString22(body, "api_mode") ?? readString22(body, "apiMode") ?? void 0,
37694
+ provider: readString23(body, "provider") ?? readString23(body, "provider_key") ?? readString23(body, "providerKey") ?? void 0,
37695
+ baseUrl: readString23(body, "base_url") ?? readString23(body, "baseUrl") ?? void 0,
37696
+ apiMode: readString23(body, "api_mode") ?? readString23(body, "apiMode") ?? void 0,
37033
37697
  setDefault: readBoolean4(body.set_default ?? body.setDefault)
37034
37698
  };
37035
37699
  }
@@ -37136,19 +37800,19 @@ function errorMessage3(error) {
37136
37800
  }
37137
37801
 
37138
37802
  // src/hermes/profile-identity.ts
37139
- import { readFile as readFile16, stat as stat18 } from "fs/promises";
37140
- import path29 from "path";
37803
+ import { readFile as readFile17, stat as stat19 } from "fs/promises";
37804
+ import path30 from "path";
37141
37805
  var MAX_SOUL_MD_LENGTH = 2e4;
37142
37806
  async function readHermesProfileIdentity(profileName, paths) {
37143
37807
  await assertProfileExists3(profileName, paths);
37144
37808
  const soulPath = resolveSoulPath(profileName);
37145
- const content = await readFile16(soulPath, "utf8").catch((error) => {
37809
+ const content = await readFile17(soulPath, "utf8").catch((error) => {
37146
37810
  if (isNodeError19(error, "ENOENT")) {
37147
37811
  return null;
37148
37812
  }
37149
37813
  throw error;
37150
37814
  });
37151
- const fileStat = content === null ? null : await stat18(soulPath).catch((error) => {
37815
+ const fileStat = content === null ? null : await stat19(soulPath).catch((error) => {
37152
37816
  if (isNodeError19(error, "ENOENT")) {
37153
37817
  return null;
37154
37818
  }
@@ -37194,7 +37858,7 @@ async function assertProfileExists3(profileName, paths) {
37194
37858
  }
37195
37859
  }
37196
37860
  function resolveSoulPath(profileName) {
37197
- return path29.join(resolveHermesProfileDir(profileName), "SOUL.md");
37861
+ return path30.join(resolveHermesProfileDir(profileName), "SOUL.md");
37198
37862
  }
37199
37863
  function isNodeError19(error, code) {
37200
37864
  return error instanceof Error && "code" in error && error.code === code;
@@ -37206,17 +37870,17 @@ import { EventEmitter as EventEmitter2 } from "events";
37206
37870
  import {
37207
37871
  cp,
37208
37872
  mkdir as mkdir13,
37209
- readFile as readFile18,
37873
+ readFile as readFile19,
37210
37874
  rm as rm7,
37211
- stat as stat20
37875
+ stat as stat21
37212
37876
  } from "fs/promises";
37213
- import path31 from "path";
37877
+ import path32 from "path";
37214
37878
  import YAML5 from "yaml";
37215
37879
 
37216
37880
  // src/hermes/link-skill.ts
37217
- import { readFile as readFile17, stat as stat19 } from "fs/promises";
37881
+ import { readFile as readFile18, stat as stat20 } from "fs/promises";
37218
37882
  import os7 from "os";
37219
- import path30 from "path";
37883
+ import path31 from "path";
37220
37884
  import YAML4 from "yaml";
37221
37885
  var HERMES_LINK_SKILL_ROOT_DIR = "hermes-skills";
37222
37886
  var HERMES_LINK_SKILL_DIR = "hermes-link";
@@ -37313,7 +37977,7 @@ Do not modify Hermes profiles, delete user data, edit config files, or kill proc
37313
37977
  async function ensureHermesLinkSkillInstalledForProfiles(options = {}) {
37314
37978
  const paths = options.paths ?? resolveRuntimePaths();
37315
37979
  const externalDir = resolveHermesLinkSkillExternalDir(paths);
37316
- const skillPath = path30.join(
37980
+ const skillPath = path31.join(
37317
37981
  externalDir,
37318
37982
  HERMES_LINK_SKILL_DIR,
37319
37983
  HERMES_LINK_SKILL_FILE
@@ -37395,10 +38059,10 @@ function withDefaultProfilePlaceholder2(profiles) {
37395
38059
  ];
37396
38060
  }
37397
38061
  function resolveHermesLinkSkillExternalDir(paths = resolveRuntimePaths()) {
37398
- return path30.join(paths.homeDir, HERMES_LINK_SKILL_ROOT_DIR);
38062
+ return path31.join(paths.homeDir, HERMES_LINK_SKILL_ROOT_DIR);
37399
38063
  }
37400
38064
  async function writeHermesLinkSkill(skillPath) {
37401
- const existing = await readFile17(skillPath, "utf8").catch((error) => {
38065
+ const existing = await readFile18(skillPath, "utf8").catch((error) => {
37402
38066
  if (isNodeError20(error, "ENOENT")) {
37403
38067
  return null;
37404
38068
  }
@@ -37456,7 +38120,7 @@ async function ensureProfileUsesExternalSkillDir(profile, externalDir) {
37456
38120
  };
37457
38121
  }
37458
38122
  async function readHermesConfigDocument3(configPath) {
37459
- const existingRaw = await readFile17(configPath, "utf8").catch(
38123
+ const existingRaw = await readFile18(configPath, "utf8").catch(
37460
38124
  (error) => {
37461
38125
  if (isNodeError20(error, "ENOENT")) {
37462
38126
  return null;
@@ -37490,11 +38154,11 @@ function appendExternalDir(current, externalDir, hermesHome) {
37490
38154
  const seen = new Set(
37491
38155
  entries.map((entry) => resolveExternalDirEntry(entry, hermesHome))
37492
38156
  );
37493
- const normalizedExternalDir = path30.resolve(externalDir);
38157
+ const normalizedExternalDir = path31.resolve(externalDir);
37494
38158
  return seen.has(normalizedExternalDir) ? entries : [...entries, normalizedExternalDir];
37495
38159
  }
37496
38160
  function externalDirsInclude(current, externalDir, hermesHome) {
37497
- const normalizedExternalDir = path30.resolve(externalDir);
38161
+ const normalizedExternalDir = path31.resolve(externalDir);
37498
38162
  return readExternalDirEntries(current).some(
37499
38163
  (entry) => resolveExternalDirEntry(entry, hermesHome) === normalizedExternalDir
37500
38164
  );
@@ -37505,14 +38169,14 @@ function readExternalDirEntries(value) {
37505
38169
  }
37506
38170
  function resolveExternalDirEntry(entry, hermesHome) {
37507
38171
  const expanded = expandHome(expandEnvVars(entry));
37508
- return path30.resolve(path30.isAbsolute(expanded) ? expanded : path30.join(hermesHome, expanded));
38172
+ return path31.resolve(path31.isAbsolute(expanded) ? expanded : path31.join(hermesHome, expanded));
37509
38173
  }
37510
38174
  function expandHome(value) {
37511
38175
  if (value === "~") {
37512
38176
  return os7.homedir();
37513
38177
  }
37514
- if (value.startsWith(`~${path30.sep}`) || value.startsWith("~/")) {
37515
- return path30.join(os7.homedir(), value.slice(2));
38178
+ if (value.startsWith(`~${path31.sep}`) || value.startsWith("~/")) {
38179
+ return path31.join(os7.homedir(), value.slice(2));
37516
38180
  }
37517
38181
  return value;
37518
38182
  }
@@ -37523,7 +38187,7 @@ function expandEnvVars(value) {
37523
38187
  );
37524
38188
  }
37525
38189
  async function pathIsDirectory2(filePath) {
37526
- return stat19(filePath).then((value) => value.isDirectory()).catch((error) => {
38190
+ return stat20(filePath).then((value) => value.isDirectory()).catch((error) => {
37527
38191
  if (isNodeError20(error, "ENOENT")) {
37528
38192
  return false;
37529
38193
  }
@@ -38064,8 +38728,8 @@ function collectEnvKeys(value, keys = /* @__PURE__ */ new Set()) {
38064
38728
  return keys;
38065
38729
  }
38066
38730
  async function writeEnvValues(profileName, values) {
38067
- const envPath = path31.join(resolveHermesProfileDir(profileName), ".env");
38068
- const existingRaw = await readFile18(envPath, "utf8").catch((error) => {
38731
+ const envPath = path32.join(resolveHermesProfileDir(profileName), ".env");
38732
+ const existingRaw = await readFile19(envPath, "utf8").catch((error) => {
38069
38733
  if (isNodeError21(error, "ENOENT")) {
38070
38734
  return "";
38071
38735
  }
@@ -38101,8 +38765,8 @@ async function writeEnvValues(profileName, values) {
38101
38765
  await atomicWriteFilePreservingMetadata(envPath, nextRaw);
38102
38766
  }
38103
38767
  async function copySkills(sourceProfile, targetProfile) {
38104
- const sourceSkills = path31.join(resolveHermesProfileDir(sourceProfile), "skills");
38105
- const targetSkills = path31.join(resolveHermesProfileDir(targetProfile), "skills");
38768
+ const sourceSkills = path32.join(resolveHermesProfileDir(sourceProfile), "skills");
38769
+ const targetSkills = path32.join(resolveHermesProfileDir(targetProfile), "skills");
38106
38770
  if (!await pathExists2(sourceSkills)) {
38107
38771
  return;
38108
38772
  }
@@ -38125,7 +38789,7 @@ function copyProperty(source, target, key) {
38125
38789
  }
38126
38790
  }
38127
38791
  async function readYamlConfig(configPath) {
38128
- const existingRaw = await readFile18(configPath, "utf8").catch(
38792
+ const existingRaw = await readFile19(configPath, "utf8").catch(
38129
38793
  (error) => {
38130
38794
  if (isNodeError21(error, "ENOENT")) {
38131
38795
  return null;
@@ -38188,7 +38852,7 @@ async function writeProfileCreationState(paths, state) {
38188
38852
  await writeJsonFile(profileCreationStatePath(paths), state);
38189
38853
  }
38190
38854
  async function readProfileCreationLogLines(paths) {
38191
- const raw = await readFile18(profileCreationLogPath(paths), "utf8").catch(() => "");
38855
+ const raw = await readFile19(profileCreationLogPath(paths), "utf8").catch(() => "");
38192
38856
  if (!raw.trim()) {
38193
38857
  return [];
38194
38858
  }
@@ -38197,10 +38861,10 @@ async function readProfileCreationLogLines(paths) {
38197
38861
  );
38198
38862
  }
38199
38863
  function profileCreationStatePath(paths) {
38200
- return path31.join(paths.runDir, "profile-create-state.json");
38864
+ return path32.join(paths.runDir, "profile-create-state.json");
38201
38865
  }
38202
38866
  function profileCreationLogPath(paths) {
38203
- return path31.join(paths.logsDir, PROFILE_CREATE_LOG_FILE);
38867
+ return path32.join(paths.logsDir, PROFILE_CREATE_LOG_FILE);
38204
38868
  }
38205
38869
  async function clearProfileCreationLogFiles(paths) {
38206
38870
  const primary = profileCreationLogPath(paths);
@@ -38213,7 +38877,7 @@ async function clearProfileCreationLogFiles(paths) {
38213
38877
  ]);
38214
38878
  }
38215
38879
  async function pathExists2(targetPath) {
38216
- return await stat20(targetPath).then(() => true).catch((error) => {
38880
+ return await stat21(targetPath).then(() => true).catch((error) => {
38217
38881
  if (isNodeError21(error, "ENOENT")) {
38218
38882
  return false;
38219
38883
  }
@@ -38346,16 +39010,16 @@ function readProfilePermissionsInput(body) {
38346
39010
  const approvals = readOptionalObject(body, "approvals");
38347
39011
  if (approvals) {
38348
39012
  input.approvals = {
38349
- mode: readString22(approvals, "mode") ?? readString22(approvals, "approval_mode") ?? readString22(approvals, "approvalMode") ?? void 0,
39013
+ mode: readString23(approvals, "mode") ?? readString23(approvals, "approval_mode") ?? readString23(approvals, "approvalMode") ?? void 0,
38350
39014
  timeout: readPositiveInteger2(approvals.timeout),
38351
- cronMode: readString22(approvals, "cron_mode") ?? readString22(approvals, "cronMode") ?? void 0
39015
+ cronMode: readString23(approvals, "cron_mode") ?? readString23(approvals, "cronMode") ?? void 0
38352
39016
  };
38353
39017
  }
38354
39018
  const terminal = readOptionalObject(body, "terminal");
38355
39019
  if (terminal) {
38356
39020
  input.terminal = {
38357
- backend: readString22(terminal, "backend") ?? void 0,
38358
- cwd: readString22(terminal, "cwd") ?? void 0,
39021
+ backend: readString23(terminal, "backend") ?? void 0,
39022
+ cwd: readString23(terminal, "cwd") ?? void 0,
38359
39023
  containerCpu: readPositiveInteger2(
38360
39024
  terminal.container_cpu ?? terminal.containerCpu
38361
39025
  ),
@@ -38486,10 +39150,10 @@ function toProfileToolConfigHttpError(error) {
38486
39150
  import {
38487
39151
  access as access3,
38488
39152
  readdir as readdir10,
38489
- readFile as readFile19,
38490
- stat as stat21
39153
+ readFile as readFile20,
39154
+ stat as stat22
38491
39155
  } from "fs/promises";
38492
- import path32 from "path";
39156
+ import path33 from "path";
38493
39157
  import YAML6 from "yaml";
38494
39158
  var ENTRY_DELIMITER = "\n\xA7\n";
38495
39159
  var DEFAULT_MEMORY_LIMIT = 2200;
@@ -38686,9 +39350,9 @@ async function testHindsightProviderSettings(profileName, patch) {
38686
39350
  const mode = normalizeHindsightMode(
38687
39351
  patch.mode ?? config.mode ?? env.HINDSIGHT_MODE
38688
39352
  );
38689
- const apiUrl = readString24(patch.apiUrl) ?? readString24(config.api_url) ?? env.HINDSIGHT_API_URL ?? (mode === "cloud" ? HINDSIGHT_DEFAULT_API_URL : HINDSIGHT_DEFAULT_LOCAL_URL);
38690
- const bankId = readString24(patch.bankId) ?? readString24(config.bank_id) ?? "hermes";
38691
- const apiKey = readString24(patch.apiKey) ?? env.HINDSIGHT_API_KEY ?? readString24(config.apiKey) ?? readString24(config.api_key);
39353
+ const apiUrl = readString25(patch.apiUrl) ?? readString25(config.api_url) ?? env.HINDSIGHT_API_URL ?? (mode === "cloud" ? HINDSIGHT_DEFAULT_API_URL : HINDSIGHT_DEFAULT_LOCAL_URL);
39354
+ const bankId = readString25(patch.bankId) ?? readString25(config.bank_id) ?? "hermes";
39355
+ const apiKey = readString25(patch.apiKey) ?? env.HINDSIGHT_API_KEY ?? readString25(config.apiKey) ?? readString25(config.api_key);
38692
39356
  const baseUrl = normalizeHttpUrl2(apiUrl);
38693
39357
  if (!baseUrl) {
38694
39358
  return {
@@ -38820,7 +39484,7 @@ async function saveProviderSettings(profileName, provider, patch) {
38820
39484
  });
38821
39485
  await patchJsonProviderConfig(
38822
39486
  profileName,
38823
- path32.join("hindsight", "config.json"),
39487
+ path33.join("hindsight", "config.json"),
38824
39488
  {
38825
39489
  mode: patch.mode,
38826
39490
  api_url: patch.apiUrl,
@@ -38968,7 +39632,7 @@ function normalizeCustomProviderId(provider) {
38968
39632
  }
38969
39633
  async function patchHermesMemoryProvider(profileName, provider) {
38970
39634
  const configPath = resolveHermesConfigPath(profileName);
38971
- const existingRaw = await readFile19(configPath, "utf8").catch(
39635
+ const existingRaw = await readFile20(configPath, "utf8").catch(
38972
39636
  (error) => {
38973
39637
  if (isNodeError22(error, "ENOENT")) {
38974
39638
  return null;
@@ -38992,7 +39656,7 @@ async function patchHermesMemoryProvider(profileName, provider) {
38992
39656
  }
38993
39657
  async function patchHermesMemoryLimits(profileName, patch) {
38994
39658
  const configPath = resolveHermesConfigPath(profileName);
38995
- const existingRaw = await readFile19(configPath, "utf8").catch(
39659
+ const existingRaw = await readFile20(configPath, "utf8").catch(
38996
39660
  (error) => {
38997
39661
  if (isNodeError22(error, "ENOENT")) {
38998
39662
  return null;
@@ -39023,12 +39687,12 @@ async function patchHermesMemoryLimits(profileName, patch) {
39023
39687
  await atomicWriteFilePreservingMetadata(configPath, document.toString());
39024
39688
  }
39025
39689
  function resolveMemoryDir(profileName) {
39026
- return path32.join(resolveHermesProfileDir(profileName), "memories");
39690
+ return path33.join(resolveHermesProfileDir(profileName), "memories");
39027
39691
  }
39028
39692
  async function readMemoryStore(profileName, target, limits) {
39029
39693
  const filePath = memoryFilePath(profileName, target);
39030
39694
  const entries = await readMemoryEntries(filePath);
39031
- const fileStat = await stat21(filePath).catch((error) => {
39695
+ const fileStat = await stat22(filePath).catch((error) => {
39032
39696
  if (isNodeError22(error, "ENOENT")) {
39033
39697
  return null;
39034
39698
  }
@@ -39057,7 +39721,7 @@ async function readMemoryStore(profileName, target, limits) {
39057
39721
  };
39058
39722
  }
39059
39723
  async function readMemoryEntries(filePath) {
39060
- const raw = await readFile19(filePath, "utf8").catch((error) => {
39724
+ const raw = await readFile20(filePath, "utf8").catch((error) => {
39061
39725
  if (isNodeError22(error, "ENOENT")) {
39062
39726
  return "";
39063
39727
  }
@@ -39084,7 +39748,7 @@ async function writeMemoryEntries(profileName, target, entries) {
39084
39748
  );
39085
39749
  }
39086
39750
  function memoryFilePath(profileName, target) {
39087
- return path32.join(
39751
+ return path33.join(
39088
39752
  resolveMemoryDir(profileName),
39089
39753
  target === "user" ? "USER.md" : "MEMORY.md"
39090
39754
  );
@@ -39144,7 +39808,7 @@ async function readCustomProviderSetupSummary(profileName) {
39144
39808
  configurable: true,
39145
39809
  configured: true,
39146
39810
  configurationIssue: null,
39147
- providerConfigPath: path32.join(
39811
+ providerConfigPath: path33.join(
39148
39812
  resolveHermesProfileDir(profileName),
39149
39813
  "<provider>.json"
39150
39814
  ),
@@ -39222,7 +39886,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
39222
39886
  const config2 = await readJsonObject(
39223
39887
  memoryProviderConfigPath(profileName, "honcho") ?? ""
39224
39888
  );
39225
- return isConfiguredEnvValue(env.HONCHO_API_KEY) || isConfiguredEnvValue(readString24(config2.apiKey)) || isConfiguredEnvValue(readString24(config2.api_key)) || isConfiguredEnvValue(readString24(config2.baseUrl)) ? { configured: true, issue: null } : {
39889
+ return isConfiguredEnvValue(env.HONCHO_API_KEY) || isConfiguredEnvValue(readString25(config2.apiKey)) || isConfiguredEnvValue(readString25(config2.api_key)) || isConfiguredEnvValue(readString25(config2.baseUrl)) ? { configured: true, issue: null } : {
39226
39890
  configured: false,
39227
39891
  issue: "Honcho \u9700\u8981\u5148\u586B\u5199 API Key\uFF0C\u6216\u5728 honcho.json \u914D\u7F6E self-hosted baseUrl\u3002"
39228
39892
  };
@@ -39231,7 +39895,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
39231
39895
  const config2 = await readJsonObject(
39232
39896
  memoryProviderConfigPath(profileName, "mem0") ?? ""
39233
39897
  );
39234
- return isConfiguredEnvValue(env.MEM0_API_KEY) || isConfiguredEnvValue(readString24(config2.api_key)) ? { configured: true, issue: null } : {
39898
+ return isConfiguredEnvValue(env.MEM0_API_KEY) || isConfiguredEnvValue(readString25(config2.api_key)) ? { configured: true, issue: null } : {
39235
39899
  configured: false,
39236
39900
  issue: "Mem0 \u9700\u8981\u5148\u5728\u672C\u9875\u586B\u5199 API Key\uFF0CLink \u4F1A\u5199\u5165\u5F53\u524D Profile \u7684 .env\u3002"
39237
39901
  };
@@ -39273,7 +39937,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
39273
39937
  memoryProviderConfigPath(profileName, provider) ?? ""
39274
39938
  );
39275
39939
  const mode = normalizeHindsightMode(config.mode ?? env.HINDSIGHT_MODE);
39276
- const apiKey = readString24(config.apiKey) ?? readString24(config.api_key) ?? env.HINDSIGHT_API_KEY;
39940
+ const apiKey = readString25(config.apiKey) ?? readString25(config.api_key) ?? env.HINDSIGHT_API_KEY;
39277
39941
  if (mode === "cloud") {
39278
39942
  return isConfiguredEnvValue(apiKey) ? { configured: true, issue: null } : {
39279
39943
  configured: false,
@@ -39281,15 +39945,15 @@ async function readProviderConfigurationStatus(profileName, provider) {
39281
39945
  };
39282
39946
  }
39283
39947
  if (mode === "local_external") {
39284
- const apiUrl = readString24(config.api_url) ?? env.HINDSIGHT_API_URL ?? HINDSIGHT_DEFAULT_LOCAL_URL;
39948
+ const apiUrl = readString25(config.api_url) ?? env.HINDSIGHT_API_URL ?? HINDSIGHT_DEFAULT_LOCAL_URL;
39285
39949
  return isConfiguredEnvValue(apiUrl) ? { configured: true, issue: null } : {
39286
39950
  configured: false,
39287
39951
  issue: "Hindsight local_external \u9700\u8981\u914D\u7F6E\u53EF\u8BBF\u95EE\u7684 API URL\u3002"
39288
39952
  };
39289
39953
  }
39290
39954
  if (mode === "local_embedded") {
39291
- const llmProvider = readString24(config.llm_provider) ?? "openai";
39292
- const llmModel = readString24(config.llm_model);
39955
+ const llmProvider = readString25(config.llm_provider) ?? "openai";
39956
+ const llmModel = readString25(config.llm_model);
39293
39957
  if (!llmModel) {
39294
39958
  return {
39295
39959
  configured: false,
@@ -39297,7 +39961,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
39297
39961
  };
39298
39962
  }
39299
39963
  if (llmProvider === "openai_compatible" && !isConfiguredEnvValue(
39300
- readString24(config.llm_base_url) ?? env.HINDSIGHT_API_LLM_BASE_URL
39964
+ readString25(config.llm_base_url) ?? env.HINDSIGHT_API_LLM_BASE_URL
39301
39965
  )) {
39302
39966
  return {
39303
39967
  configured: false,
@@ -39305,7 +39969,7 @@ async function readProviderConfigurationStatus(profileName, provider) {
39305
39969
  };
39306
39970
  }
39307
39971
  if (!["ollama", "lmstudio", "openai_compatible"].includes(llmProvider) && !isConfiguredEnvValue(
39308
- readString24(config.llmApiKey) ?? readString24(config.llm_api_key) ?? env.HINDSIGHT_LLM_API_KEY
39972
+ readString25(config.llmApiKey) ?? readString25(config.llm_api_key) ?? env.HINDSIGHT_LLM_API_KEY
39309
39973
  )) {
39310
39974
  return {
39311
39975
  configured: false,
@@ -39361,8 +40025,8 @@ async function readProviderSettings(profileName, provider) {
39361
40025
  secretSetting(
39362
40026
  "apiKey",
39363
40027
  "API Key",
39364
- env.HONCHO_API_KEY ?? readString24(config.apiKey) ?? readString24(config.api_key),
39365
- isConfiguredEnvValue(env.HONCHO_API_KEY) || isConfiguredEnvValue(readString24(config.apiKey)) || isConfiguredEnvValue(readString24(config.api_key))
40028
+ env.HONCHO_API_KEY ?? readString25(config.apiKey) ?? readString25(config.api_key),
40029
+ isConfiguredEnvValue(env.HONCHO_API_KEY) || isConfiguredEnvValue(readString25(config.apiKey)) || isConfiguredEnvValue(readString25(config.api_key))
39366
40030
  ),
39367
40031
  stringSetting("workspace", "Workspace", config.workspace ?? "hermes"),
39368
40032
  stringSetting("peerName", "\u7528\u6237 Peer", config.peerName ?? ""),
@@ -39404,8 +40068,8 @@ async function readProviderSettings(profileName, provider) {
39404
40068
  secretSetting(
39405
40069
  "apiKey",
39406
40070
  "API Key",
39407
- env.MEM0_API_KEY ?? readString24(config.apiKey) ?? readString24(config.api_key),
39408
- isConfiguredEnvValue(env.MEM0_API_KEY) || isConfiguredEnvValue(readString24(config.apiKey)) || isConfiguredEnvValue(readString24(config.api_key))
40071
+ env.MEM0_API_KEY ?? readString25(config.apiKey) ?? readString25(config.api_key),
40072
+ isConfiguredEnvValue(env.MEM0_API_KEY) || isConfiguredEnvValue(readString25(config.apiKey)) || isConfiguredEnvValue(readString25(config.api_key))
39409
40073
  ),
39410
40074
  stringSetting("userId", "User ID", config.user_id ?? "hermes-user"),
39411
40075
  stringSetting("agentId", "Agent ID", config.agent_id ?? "hermes"),
@@ -39490,8 +40154,8 @@ async function readProviderSettings(profileName, provider) {
39490
40154
  secretSetting(
39491
40155
  "apiKey",
39492
40156
  "Hindsight API Key",
39493
- env.HINDSIGHT_API_KEY ?? readString24(config.apiKey) ?? readString24(config.api_key),
39494
- isConfiguredEnvValue(env.HINDSIGHT_API_KEY) || isConfiguredEnvValue(readString24(config.apiKey)) || isConfiguredEnvValue(readString24(config.api_key))
40157
+ env.HINDSIGHT_API_KEY ?? readString25(config.apiKey) ?? readString25(config.api_key),
40158
+ isConfiguredEnvValue(env.HINDSIGHT_API_KEY) || isConfiguredEnvValue(readString25(config.apiKey)) || isConfiguredEnvValue(readString25(config.api_key))
39495
40159
  ),
39496
40160
  stringSetting(
39497
40161
  "bankId",
@@ -39513,8 +40177,8 @@ async function readProviderSettings(profileName, provider) {
39513
40177
  secretSetting(
39514
40178
  "llmApiKey",
39515
40179
  "LLM API Key",
39516
- env.HINDSIGHT_LLM_API_KEY ?? readString24(config.llmApiKey) ?? readString24(config.llm_api_key),
39517
- isConfiguredEnvValue(env.HINDSIGHT_LLM_API_KEY) || isConfiguredEnvValue(readString24(config.llmApiKey)) || isConfiguredEnvValue(readString24(config.llm_api_key))
40180
+ env.HINDSIGHT_LLM_API_KEY ?? readString25(config.llmApiKey) ?? readString25(config.llm_api_key),
40181
+ isConfiguredEnvValue(env.HINDSIGHT_LLM_API_KEY) || isConfiguredEnvValue(readString25(config.llmApiKey)) || isConfiguredEnvValue(readString25(config.llm_api_key))
39518
40182
  ),
39519
40183
  booleanSetting("autoRecall", "\u81EA\u52A8\u56DE\u5FC6", config.auto_recall ?? true),
39520
40184
  booleanSetting("autoRetain", "\u81EA\u52A8\u6C89\u6DC0", config.auto_retain ?? true),
@@ -39538,7 +40202,7 @@ async function readProviderSettings(profileName, provider) {
39538
40202
  stringSetting(
39539
40203
  "dbPath",
39540
40204
  "SQLite \u6570\u636E\u5E93\u8DEF\u5F84",
39541
- config.db_path ?? path32.join(resolveHermesProfileDir(profileName), "memory_store.db")
40205
+ config.db_path ?? path33.join(resolveHermesProfileDir(profileName), "memory_store.db")
39542
40206
  ),
39543
40207
  booleanSetting("autoExtract", "\u4F1A\u8BDD\u7ED3\u675F\u81EA\u52A8\u62BD\u53D6", config.auto_extract ?? false),
39544
40208
  numberSetting("defaultTrust", "\u9ED8\u8BA4\u4FE1\u4EFB\u5206", config.default_trust ?? 0.5),
@@ -39574,7 +40238,7 @@ async function readProviderSettings(profileName, provider) {
39574
40238
  stringSetting(
39575
40239
  "workingDirectory",
39576
40240
  "\u5DE5\u4F5C\u76EE\u5F55",
39577
- path32.join(resolveHermesProfileDir(profileName), "byterover"),
40241
+ path33.join(resolveHermesProfileDir(profileName), "byterover"),
39578
40242
  false
39579
40243
  )
39580
40244
  ];
@@ -39583,16 +40247,16 @@ async function readProviderSettings(profileName, provider) {
39583
40247
  }
39584
40248
  function memoryProviderConfigPath(profileName, provider) {
39585
40249
  if (provider === "honcho") {
39586
- return path32.join(resolveHermesProfileDir(profileName), "honcho.json");
40250
+ return path33.join(resolveHermesProfileDir(profileName), "honcho.json");
39587
40251
  }
39588
40252
  if (provider === "mem0") {
39589
- return path32.join(resolveHermesProfileDir(profileName), "mem0.json");
40253
+ return path33.join(resolveHermesProfileDir(profileName), "mem0.json");
39590
40254
  }
39591
40255
  if (provider === "supermemory") {
39592
- return path32.join(resolveHermesProfileDir(profileName), "supermemory.json");
40256
+ return path33.join(resolveHermesProfileDir(profileName), "supermemory.json");
39593
40257
  }
39594
40258
  if (provider === "hindsight") {
39595
- return path32.join(
40259
+ return path33.join(
39596
40260
  resolveHermesProfileDir(profileName),
39597
40261
  "hindsight",
39598
40262
  "config.json"
@@ -39601,19 +40265,19 @@ function memoryProviderConfigPath(profileName, provider) {
39601
40265
  return null;
39602
40266
  }
39603
40267
  function customProviderConfigPath(profileName, provider) {
39604
- return path32.join(
40268
+ return path33.join(
39605
40269
  resolveHermesProfileDir(profileName),
39606
40270
  `${normalizeCustomProviderId(provider)}.json`
39607
40271
  );
39608
40272
  }
39609
40273
  function customProviderRegistryPath(profileName) {
39610
- return path32.join(
40274
+ return path33.join(
39611
40275
  resolveHermesProfileDir(profileName),
39612
40276
  CUSTOM_PROVIDER_REGISTRY_FILE
39613
40277
  );
39614
40278
  }
39615
40279
  async function readCustomProviderRegistry(profileName) {
39616
- const raw = await readFile19(customProviderRegistryPath(profileName), "utf8").catch(
40280
+ const raw = await readFile20(customProviderRegistryPath(profileName), "utf8").catch(
39617
40281
  (error) => {
39618
40282
  if (isNodeError22(error, "ENOENT")) {
39619
40283
  return "";
@@ -39633,11 +40297,11 @@ async function readCustomProviderRegistry(profileName) {
39633
40297
  return { id: id2, label: id2, description: "\u81EA\u5B9A\u4E49 memory provider\u3002" };
39634
40298
  }
39635
40299
  const record = toRecord22(item);
39636
- const id = normalizeCustomProviderId(readString24(record.id) ?? "");
40300
+ const id = normalizeCustomProviderId(readString25(record.id) ?? "");
39637
40301
  return {
39638
40302
  id,
39639
- label: readString24(record.label) ?? id,
39640
- description: readString24(record.description) ?? "\u81EA\u5B9A\u4E49 memory provider\u3002"
40303
+ label: readString25(record.label) ?? id,
40304
+ description: readString25(record.description) ?? "\u81EA\u5B9A\u4E49 memory provider\u3002"
39641
40305
  };
39642
40306
  }).filter((item) => item.id);
39643
40307
  } catch {
@@ -39659,7 +40323,7 @@ async function saveCustomProviderRegistryEntry(profileName, provider) {
39659
40323
  );
39660
40324
  }
39661
40325
  async function discoverUserMemoryProviderDescriptors(profileName) {
39662
- const pluginsDir = path32.join(resolveHermesProfileDir(profileName), "plugins");
40326
+ const pluginsDir = path33.join(resolveHermesProfileDir(profileName), "plugins");
39663
40327
  const entries = await readdir10(pluginsDir, { withFileTypes: true }).catch(
39664
40328
  (error) => {
39665
40329
  if (isNodeError22(error, "ENOENT")) {
@@ -39679,21 +40343,21 @@ async function discoverUserMemoryProviderDescriptors(profileName) {
39679
40343
  } catch {
39680
40344
  continue;
39681
40345
  }
39682
- const providerDir = path32.join(pluginsDir, entry.name);
40346
+ const providerDir = path33.join(pluginsDir, entry.name);
39683
40347
  if (!await isMemoryProviderPluginDir(providerDir)) {
39684
40348
  continue;
39685
40349
  }
39686
40350
  const meta = await readPluginMetadata(providerDir);
39687
40351
  descriptors.push({
39688
40352
  id: providerId,
39689
- label: readString24(meta.name) ?? providerId,
39690
- description: readString24(meta.description) ?? "\u81EA\u5B9A\u4E49 memory provider\u3002"
40353
+ label: readString25(meta.name) ?? providerId,
40354
+ description: readString25(meta.description) ?? "\u81EA\u5B9A\u4E49 memory provider\u3002"
39691
40355
  });
39692
40356
  }
39693
40357
  return descriptors;
39694
40358
  }
39695
40359
  async function isUserMemoryProviderInstalled(profileName, provider) {
39696
- const providerDir = path32.join(
40360
+ const providerDir = path33.join(
39697
40361
  resolveHermesProfileDir(profileName),
39698
40362
  "plugins",
39699
40363
  normalizeCustomProviderId(provider)
@@ -39701,7 +40365,7 @@ async function isUserMemoryProviderInstalled(profileName, provider) {
39701
40365
  return isMemoryProviderPluginDir(providerDir);
39702
40366
  }
39703
40367
  async function isMemoryProviderPluginDir(providerDir) {
39704
- const source = await readFile19(path32.join(providerDir, "__init__.py"), "utf8").catch(
40368
+ const source = await readFile20(path33.join(providerDir, "__init__.py"), "utf8").catch(
39705
40369
  (error) => {
39706
40370
  if (isNodeError22(error, "ENOENT")) {
39707
40371
  return "";
@@ -39713,7 +40377,7 @@ async function isMemoryProviderPluginDir(providerDir) {
39713
40377
  return sample.includes("register_memory_provider") || sample.includes("MemoryProvider");
39714
40378
  }
39715
40379
  async function readPluginMetadata(providerDir) {
39716
- const raw = await readFile19(path32.join(providerDir, "plugin.yaml"), "utf8").catch(
40380
+ const raw = await readFile20(path33.join(providerDir, "plugin.yaml"), "utf8").catch(
39717
40381
  (error) => {
39718
40382
  if (isNodeError22(error, "ENOENT")) {
39719
40383
  return "";
@@ -39725,10 +40389,10 @@ async function readPluginMetadata(providerDir) {
39725
40389
  }
39726
40390
  async function resolveByteRoverCli() {
39727
40391
  const candidates = [
39728
- ...(process.env.PATH ?? "").split(path32.delimiter).filter(Boolean).map((dir) => path32.join(dir, "brv")),
39729
- path32.join(process.env.HOME ?? "", ".brv-cli", "bin", "brv"),
40392
+ ...(process.env.PATH ?? "").split(path33.delimiter).filter(Boolean).map((dir) => path33.join(dir, "brv")),
40393
+ path33.join(process.env.HOME ?? "", ".brv-cli", "bin", "brv"),
39730
40394
  "/usr/local/bin/brv",
39731
- path32.join(process.env.HOME ?? "", ".npm-global", "bin", "brv")
40395
+ path33.join(process.env.HOME ?? "", ".npm-global", "bin", "brv")
39732
40396
  ].filter(Boolean);
39733
40397
  for (const candidate of candidates) {
39734
40398
  const found = await access3(candidate).then(() => true).catch(() => false);
@@ -39739,7 +40403,7 @@ async function resolveByteRoverCli() {
39739
40403
  return null;
39740
40404
  }
39741
40405
  async function readHolographicProviderConfig(profileName) {
39742
- const raw = await readFile19(resolveHermesConfigPath(profileName), "utf8").catch(
40406
+ const raw = await readFile20(resolveHermesConfigPath(profileName), "utf8").catch(
39743
40407
  (error) => {
39744
40408
  if (isNodeError22(error, "ENOENT")) {
39745
40409
  return "";
@@ -39753,7 +40417,7 @@ async function readHolographicProviderConfig(profileName) {
39753
40417
  }
39754
40418
  async function patchHolographicProviderConfig(profileName, patch) {
39755
40419
  const configPath = resolveHermesConfigPath(profileName);
39756
- const existingRaw = await readFile19(configPath, "utf8").catch(
40420
+ const existingRaw = await readFile20(configPath, "utf8").catch(
39757
40421
  (error) => {
39758
40422
  if (isNodeError22(error, "ENOENT")) {
39759
40423
  return null;
@@ -39789,8 +40453,8 @@ async function patchHermesMemoryEnv(profileName, patch) {
39789
40453
  if (entries.length === 0) {
39790
40454
  return;
39791
40455
  }
39792
- const envPath = path32.join(resolveHermesProfileDir(profileName), ".env");
39793
- const existingRaw = await readFile19(envPath, "utf8").catch((error) => {
40456
+ const envPath = path33.join(resolveHermesProfileDir(profileName), ".env");
40457
+ const existingRaw = await readFile20(envPath, "utf8").catch((error) => {
39794
40458
  if (isNodeError22(error, "ENOENT")) {
39795
40459
  return "";
39796
40460
  }
@@ -39849,7 +40513,7 @@ function isMemoryEnvKeyWritable(key) {
39849
40513
  ].includes(key);
39850
40514
  }
39851
40515
  function normalizeHindsightMode(value) {
39852
- const mode = readString24(value) ?? "cloud";
40516
+ const mode = readString25(value) ?? "cloud";
39853
40517
  return mode === "local" ? "local_embedded" : mode;
39854
40518
  }
39855
40519
  function normalizeHttpUrl2(value) {
@@ -39918,31 +40582,31 @@ function parseJsonObject2(text) {
39918
40582
  }
39919
40583
  }
39920
40584
  function readHindsightError(json) {
39921
- const detail = readString24(json.detail) ?? readString24(json.error);
40585
+ const detail = readString25(json.detail) ?? readString25(json.error);
39922
40586
  return detail ? `\uFF1A${detail}` : "";
39923
40587
  }
39924
40588
  function hindsightSemanticIssue(pathName, json) {
39925
40589
  if (pathName === "/health") {
39926
- const status = readString24(json.status);
40590
+ const status = readString25(json.status);
39927
40591
  return status && ["healthy", "ok"].includes(status.toLowerCase()) ? null : `\u5065\u5EB7\u72B6\u6001\u5F02\u5E38\uFF1A${status ?? "unknown"}`;
39928
40592
  }
39929
40593
  return null;
39930
40594
  }
39931
40595
  function summarizeHindsightProbe(pathName, json) {
39932
40596
  if (pathName === "/health") {
39933
- const status = readString24(json.status) ?? "ok";
39934
- const database = readString24(json.database);
40597
+ const status = readString25(json.status) ?? "ok";
40598
+ const database = readString25(json.database);
39935
40599
  return database ? `${status}, database ${database}` : status;
39936
40600
  }
39937
40601
  if (pathName === "/version") {
39938
- const version = readString24(json.api_version);
40602
+ const version = readString25(json.api_version);
39939
40603
  return version ? `API ${version}` : "version endpoint reachable";
39940
40604
  }
39941
- const bankId = readString24(json.bank_id);
40605
+ const bankId = readString25(json.bank_id);
39942
40606
  return bankId ? `bank ${bankId} reachable` : "bank config reachable";
39943
40607
  }
39944
40608
  async function readActiveMemoryProvider(profileName) {
39945
- const raw = await readFile19(
40609
+ const raw = await readFile20(
39946
40610
  resolveHermesConfigPath(profileName),
39947
40611
  "utf8"
39948
40612
  ).catch((error) => {
@@ -39953,14 +40617,14 @@ async function readActiveMemoryProvider(profileName) {
39953
40617
  });
39954
40618
  const config = raw ? toRecord22(YAML6.parse(raw)) : {};
39955
40619
  const memory = toRecord22(config.memory);
39956
- const provider = readString24(memory.provider);
40620
+ const provider = readString25(memory.provider);
39957
40621
  if (!provider || provider === "built-in" || provider === "builtin" || provider === "built_in") {
39958
40622
  return null;
39959
40623
  }
39960
40624
  return provider;
39961
40625
  }
39962
40626
  async function patchJsonProviderConfig(profileName, relativePath, patch) {
39963
- const configPath = path32.join(
40627
+ const configPath = path33.join(
39964
40628
  resolveHermesProfileDir(profileName),
39965
40629
  relativePath
39966
40630
  );
@@ -39978,7 +40642,7 @@ async function patchJsonProviderConfig(profileName, relativePath, patch) {
39978
40642
  );
39979
40643
  }
39980
40644
  async function readJsonObject(filePath) {
39981
- const raw = await readFile19(filePath, "utf8").catch((error) => {
40645
+ const raw = await readFile20(filePath, "utf8").catch((error) => {
39982
40646
  if (isNodeError22(error, "ENOENT")) {
39983
40647
  return "{}";
39984
40648
  }
@@ -39989,7 +40653,7 @@ async function readJsonObject(filePath) {
39989
40653
  } catch {
39990
40654
  throw new HermesMemoryError(
39991
40655
  "memory_provider_config_invalid",
39992
- `${path32.basename(filePath)} \u4E0D\u662F\u6709\u6548\u7684 JSON \u914D\u7F6E\u6587\u4EF6\u3002`
40656
+ `${path33.basename(filePath)} \u4E0D\u662F\u6709\u6548\u7684 JSON \u914D\u7F6E\u6587\u4EF6\u3002`
39993
40657
  );
39994
40658
  }
39995
40659
  }
@@ -40010,7 +40674,7 @@ function stringSetting(key, label, value, editable = true) {
40010
40674
  return {
40011
40675
  key,
40012
40676
  label,
40013
- value: readString24(value) ?? "",
40677
+ value: readString25(value) ?? "",
40014
40678
  editable,
40015
40679
  kind: "string"
40016
40680
  };
@@ -40022,7 +40686,7 @@ function secretSetting(key, label, value, configured) {
40022
40686
  value: "",
40023
40687
  editable: true,
40024
40688
  kind: "secret",
40025
- configured: configured || isConfiguredEnvValue(readString24(value))
40689
+ configured: configured || isConfiguredEnvValue(readString25(value))
40026
40690
  };
40027
40691
  }
40028
40692
  function textSetting(key, label, value, editable = true) {
@@ -40035,11 +40699,11 @@ function textSetting(key, label, value, editable = true) {
40035
40699
  };
40036
40700
  }
40037
40701
  function selectSetting(key, label, value, options, editable = true) {
40038
- const stringValue = readString24(value) ?? options[0] ?? null;
40702
+ const stringValue = readString25(value) ?? options[0] ?? null;
40039
40703
  return { key, label, value: stringValue, editable, kind: "select", options };
40040
40704
  }
40041
40705
  async function readMemoryLimits(profileName) {
40042
- const raw = await readFile19(
40706
+ const raw = await readFile20(
40043
40707
  resolveHermesConfigPath(profileName),
40044
40708
  "utf8"
40045
40709
  ).catch((error) => {
@@ -40108,7 +40772,7 @@ function hashString(value) {
40108
40772
  function toRecord22(value) {
40109
40773
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
40110
40774
  }
40111
- function readString24(value) {
40775
+ function readString25(value) {
40112
40776
  return typeof value === "string" && value.trim() ? value.trim() : null;
40113
40777
  }
40114
40778
  function readPositiveInteger4(value) {
@@ -40267,7 +40931,7 @@ function registerProfileMemoryRoutes(router, options) {
40267
40931
  );
40268
40932
  }
40269
40933
  function readMemoryTarget(body) {
40270
- const raw = readString22(body, "target");
40934
+ const raw = readString23(body, "target");
40271
40935
  if (raw === "memory" || raw === "user") {
40272
40936
  return raw;
40273
40937
  }
@@ -40278,7 +40942,7 @@ function readMemoryTarget(body) {
40278
40942
  );
40279
40943
  }
40280
40944
  function readMemoryResetTarget(body) {
40281
- const raw = readString22(body, "target") ?? "all";
40945
+ const raw = readString23(body, "target") ?? "all";
40282
40946
  if (raw === "all" || raw === "memory" || raw === "user") {
40283
40947
  return raw;
40284
40948
  }
@@ -40289,7 +40953,7 @@ function readMemoryResetTarget(body) {
40289
40953
  );
40290
40954
  }
40291
40955
  function readRequiredMemoryContent(body) {
40292
- const content = readString22(body, "content") ?? readString22(body, "text");
40956
+ const content = readString23(body, "content") ?? readString23(body, "text");
40293
40957
  if (!content) {
40294
40958
  throw new LinkHttpError(
40295
40959
  400,
@@ -40300,7 +40964,7 @@ function readRequiredMemoryContent(body) {
40300
40964
  return content;
40301
40965
  }
40302
40966
  function readRequiredMemoryMatch(body) {
40303
- const oldText = readString22(body, "old_text") ?? readString22(body, "oldText") ?? readString22(body, "match");
40967
+ const oldText = readString23(body, "old_text") ?? readString23(body, "oldText") ?? readString23(body, "match");
40304
40968
  if (!oldText) {
40305
40969
  throw new LinkHttpError(
40306
40970
  400,
@@ -40311,7 +40975,7 @@ function readRequiredMemoryMatch(body) {
40311
40975
  return oldText;
40312
40976
  }
40313
40977
  function readRequiredMemoryProvider(body) {
40314
- const provider = readString22(body, "provider") ?? readString22(body, "provider_id") ?? readString22(body, "providerId");
40978
+ const provider = readString23(body, "provider") ?? readString23(body, "provider_id") ?? readString23(body, "providerId");
40315
40979
  if (!provider) {
40316
40980
  throw new LinkHttpError(
40317
40981
  400,
@@ -40341,7 +41005,7 @@ function readMemorySettingsPatch(body, options = {}) {
40341
41005
  input.userCharLimit = userCharLimit;
40342
41006
  }
40343
41007
  }
40344
- const mode = readString22(body, "mode");
41008
+ const mode = readString23(body, "mode");
40345
41009
  if (mode) {
40346
41010
  input.mode = mode;
40347
41011
  }
@@ -40357,7 +41021,7 @@ function readMemorySettingsPatch(body, options = {}) {
40357
41021
  if (bankId !== void 0) {
40358
41022
  input.bankId = bankId;
40359
41023
  }
40360
- const llmProvider = readString22(body, "llm_provider") ?? readString22(body, "llmProvider");
41024
+ const llmProvider = readString23(body, "llm_provider") ?? readString23(body, "llmProvider");
40361
41025
  if (llmProvider) {
40362
41026
  input.llmProvider = llmProvider;
40363
41027
  }
@@ -40393,11 +41057,11 @@ function readMemorySettingsPatch(body, options = {}) {
40393
41057
  if (autoRetain !== void 0) {
40394
41058
  input.autoRetain = autoRetain;
40395
41059
  }
40396
- const memoryMode = readString22(body, "memory_mode") ?? readString22(body, "memoryMode");
41060
+ const memoryMode = readString23(body, "memory_mode") ?? readString23(body, "memoryMode");
40397
41061
  if (memoryMode) {
40398
41062
  input.memoryMode = memoryMode;
40399
41063
  }
40400
- const recallBudget = readString22(body, "recall_budget") ?? readString22(body, "recallBudget");
41064
+ const recallBudget = readString23(body, "recall_budget") ?? readString23(body, "recallBudget");
40401
41065
  if (recallBudget) {
40402
41066
  input.recallBudget = recallBudget;
40403
41067
  }
@@ -40413,11 +41077,11 @@ function readMemorySettingsPatch(body, options = {}) {
40413
41077
  if (profileFrequency !== void 0) {
40414
41078
  input.profileFrequency = profileFrequency;
40415
41079
  }
40416
- const captureMode = readString22(body, "capture_mode") ?? readString22(body, "captureMode");
41080
+ const captureMode = readString23(body, "capture_mode") ?? readString23(body, "captureMode");
40417
41081
  if (captureMode) {
40418
41082
  input.captureMode = captureMode;
40419
41083
  }
40420
- const searchMode = readString22(body, "search_mode") ?? readString22(body, "searchMode");
41084
+ const searchMode = readString23(body, "search_mode") ?? readString23(body, "searchMode");
40421
41085
  if (searchMode) {
40422
41086
  input.searchMode = searchMode;
40423
41087
  }
@@ -40451,11 +41115,11 @@ function readMemorySettingsPatch(body, options = {}) {
40451
41115
  if (aiPeer !== void 0) {
40452
41116
  input.aiPeer = aiPeer;
40453
41117
  }
40454
- const recallMode = readString22(body, "recall_mode") ?? readString22(body, "recallMode");
41118
+ const recallMode = readString23(body, "recall_mode") ?? readString23(body, "recallMode");
40455
41119
  if (recallMode) {
40456
41120
  input.recallMode = recallMode;
40457
41121
  }
40458
- const writeFrequency = readString22(body, "write_frequency") ?? readString22(body, "writeFrequency");
41122
+ const writeFrequency = readString23(body, "write_frequency") ?? readString23(body, "writeFrequency");
40459
41123
  if (writeFrequency) {
40460
41124
  input.writeFrequency = writeFrequency;
40461
41125
  }
@@ -40463,7 +41127,7 @@ function readMemorySettingsPatch(body, options = {}) {
40463
41127
  if (saveMessages !== void 0) {
40464
41128
  input.saveMessages = saveMessages;
40465
41129
  }
40466
- const sessionStrategy = readString22(body, "session_strategy") ?? readString22(body, "sessionStrategy");
41130
+ const sessionStrategy = readString23(body, "session_strategy") ?? readString23(body, "sessionStrategy");
40467
41131
  if (sessionStrategy) {
40468
41132
  input.sessionStrategy = sessionStrategy;
40469
41133
  }
@@ -40612,8 +41276,8 @@ function toMemoryHttpError(error) {
40612
41276
  }
40613
41277
 
40614
41278
  // src/hermes/skills.ts
40615
- import { readFile as readFile20, readdir as readdir11 } from "fs/promises";
40616
- import path33 from "path";
41279
+ import { readFile as readFile21, readdir as readdir11 } from "fs/promises";
41280
+ import path34 from "path";
40617
41281
  import YAML7 from "yaml";
40618
41282
  var HermesSkillNotFoundError = class extends Error {
40619
41283
  constructor(skillName) {
@@ -40627,7 +41291,7 @@ var EXCLUDED_SKILL_DIRS = /* @__PURE__ */ new Set([".git", ".github", ".hub"]);
40627
41291
  async function listHermesProfileSkills(profileName, paths = resolveRuntimePaths()) {
40628
41292
  const profile = await readExistingProfile(profileName, paths);
40629
41293
  const profileDir = resolveHermesProfileDir(profile.name);
40630
- const skillsRoot = path33.join(profileDir, "skills");
41294
+ const skillsRoot = path34.join(profileDir, "skills");
40631
41295
  const [skillFiles, disabled, provenance] = await Promise.all([
40632
41296
  findSkillFiles(skillsRoot),
40633
41297
  readDisabledSkillNames(resolveHermesConfigPath(profile.name)),
@@ -40718,7 +41382,7 @@ async function collectSkillFiles(directory, results) {
40718
41382
  if (EXCLUDED_SKILL_DIRS.has(entry.name)) {
40719
41383
  continue;
40720
41384
  }
40721
- const entryPath = path33.join(directory, entry.name);
41385
+ const entryPath = path34.join(directory, entry.name);
40722
41386
  if (entry.isDirectory()) {
40723
41387
  await collectSkillFiles(entryPath, results);
40724
41388
  continue;
@@ -40729,7 +41393,7 @@ async function collectSkillFiles(directory, results) {
40729
41393
  }
40730
41394
  }
40731
41395
  async function readSkillMetadata(input) {
40732
- const raw = await readFile20(input.skillFile, "utf8").catch(
41396
+ const raw = await readFile21(input.skillFile, "utf8").catch(
40733
41397
  (error) => {
40734
41398
  if (isNodeError23(error, "ENOENT") || isNodeError23(error, "EACCES")) {
40735
41399
  return null;
@@ -40740,16 +41404,16 @@ async function readSkillMetadata(input) {
40740
41404
  if (raw === null) {
40741
41405
  return null;
40742
41406
  }
40743
- const skillDir = path33.dirname(input.skillFile);
41407
+ const skillDir = path34.dirname(input.skillFile);
40744
41408
  const { frontmatter, body } = parseSkillDocument(raw.slice(0, 4e3));
40745
41409
  const name = normalizeSkillName(
40746
- readString25(frontmatter.name) ?? path33.basename(skillDir)
41410
+ readString26(frontmatter.name) ?? path34.basename(skillDir)
40747
41411
  );
40748
41412
  if (!name) {
40749
41413
  return null;
40750
41414
  }
40751
41415
  const description = normalizeDescription(
40752
- readString25(frontmatter.description) ?? firstBodyDescription(body)
41416
+ readString26(frontmatter.description) ?? firstBodyDescription(body)
40753
41417
  );
40754
41418
  const provenance = input.provenance.get(name) ?? {
40755
41419
  source: "local",
@@ -40762,7 +41426,7 @@ async function readSkillMetadata(input) {
40762
41426
  enabled: !input.disabled.has(name),
40763
41427
  source: provenance.source,
40764
41428
  trust: provenance.trust,
40765
- relativePath: path33.relative(input.skillsRoot, skillDir)
41429
+ relativePath: path34.relative(input.skillsRoot, skillDir)
40766
41430
  };
40767
41431
  }
40768
41432
  function parseSkillDocument(raw) {
@@ -40783,8 +41447,8 @@ function parseSkillDocument(raw) {
40783
41447
  }
40784
41448
  }
40785
41449
  function categoryFromPath(skillsRoot, skillFile) {
40786
- const relative = path33.relative(skillsRoot, skillFile);
40787
- const parts = relative.split(path33.sep).filter(Boolean);
41450
+ const relative = path34.relative(skillsRoot, skillFile);
41451
+ const parts = relative.split(path34.sep).filter(Boolean);
40788
41452
  return parts.length >= 3 ? parts[0] : null;
40789
41453
  }
40790
41454
  function firstBodyDescription(body) {
@@ -40807,7 +41471,7 @@ function normalizeDescription(value) {
40807
41471
  return `${description.slice(0, MAX_DESCRIPTION_LENGTH - 3)}...`;
40808
41472
  }
40809
41473
  async function readDisabledSkillNames(configPath) {
40810
- const raw = await readFile20(configPath, "utf8").catch((error) => {
41474
+ const raw = await readFile21(configPath, "utf8").catch((error) => {
40811
41475
  if (isNodeError23(error, "ENOENT")) {
40812
41476
  return "";
40813
41477
  }
@@ -40831,7 +41495,7 @@ async function readSkillProvenance(root) {
40831
41495
  return provenance;
40832
41496
  }
40833
41497
  async function readBundledSkillNames(root) {
40834
- const raw = await readFile20(path33.join(root, ".bundled_manifest"), "utf8").catch(
41498
+ const raw = await readFile21(path34.join(root, ".bundled_manifest"), "utf8").catch(
40835
41499
  (error) => {
40836
41500
  if (isNodeError23(error, "ENOENT")) {
40837
41501
  return "";
@@ -40854,7 +41518,7 @@ async function readBundledSkillNames(root) {
40854
41518
  return names;
40855
41519
  }
40856
41520
  async function readHubInstalledSkills(root) {
40857
- const raw = await readFile20(path33.join(root, ".hub", "lock.json"), "utf8").catch(
41521
+ const raw = await readFile21(path34.join(root, ".hub", "lock.json"), "utf8").catch(
40858
41522
  (error) => {
40859
41523
  if (isNodeError23(error, "ENOENT")) {
40860
41524
  return "";
@@ -40876,8 +41540,8 @@ async function readHubInstalledSkills(root) {
40876
41540
  for (const [name, rawEntry] of Object.entries(installed2)) {
40877
41541
  const entry = toRecord23(rawEntry);
40878
41542
  result.set(normalizeSkillName(name), {
40879
- source: readString25(entry.source) ?? "hub",
40880
- trust: readString25(entry.trust_level) ?? null
41543
+ source: readString26(entry.source) ?? "hub",
41544
+ trust: readString26(entry.trust_level) ?? null
40881
41545
  });
40882
41546
  }
40883
41547
  return result;
@@ -40926,7 +41590,7 @@ function compareCategoryNames(left, right) {
40926
41590
  return left.localeCompare(right);
40927
41591
  }
40928
41592
  async function readHermesConfigDocument4(configPath) {
40929
- const existingRaw = await readFile20(configPath, "utf8").catch(
41593
+ const existingRaw = await readFile21(configPath, "utf8").catch(
40930
41594
  (error) => {
40931
41595
  if (isNodeError23(error, "ENOENT")) {
40932
41596
  return null;
@@ -40961,7 +41625,7 @@ function readStringList6(value) {
40961
41625
  }
40962
41626
  return value.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
40963
41627
  }
40964
- function readString25(value) {
41628
+ function readString26(value) {
40965
41629
  return typeof value === "string" && value.trim() ? value.trim() : null;
40966
41630
  }
40967
41631
  function toRecord23(value) {
@@ -41333,7 +41997,7 @@ function registerRunRoutes(router, options) {
41333
41997
  await authenticateRequest(ctx, paths);
41334
41998
  const language = readPreferredLanguage(ctx);
41335
41999
  const body = await readJsonBody(ctx.req);
41336
- const input = readString22(body, "input");
42000
+ const input = readString23(body, "input");
41337
42001
  if (!input) {
41338
42002
  throw new LinkHttpError(400, "run_input_required", "input is required");
41339
42003
  }
@@ -41341,12 +42005,12 @@ function registerRunRoutes(router, options) {
41341
42005
  ctx.body = await createHermesRun(
41342
42006
  {
41343
42007
  input,
41344
- instructions: readString22(body, "instructions") ?? void 0,
42008
+ instructions: readString23(body, "instructions") ?? void 0,
41345
42009
  conversation_history: readConversationHistory(
41346
42010
  body.conversation_history ?? body.conversationHistory
41347
42011
  ),
41348
- session_id: readString22(body, "session_id") ?? readString22(body, "sessionId") ?? void 0,
41349
- session_key: readString22(body, "session_key") ?? readString22(body, "sessionKey") ?? void 0
42012
+ session_id: readString23(body, "session_id") ?? readString23(body, "sessionId") ?? void 0,
42013
+ session_key: readString23(body, "session_key") ?? readString23(body, "sessionKey") ?? void 0
41350
42014
  },
41351
42015
  { logger, profileName: readOptionalProfileName(body), language }
41352
42016
  );
@@ -41521,8 +42185,8 @@ function readModelList(payload) {
41521
42185
  // src/hermes/updates.ts
41522
42186
  import { EventEmitter as EventEmitter3 } from "events";
41523
42187
  import { spawn as spawn4 } from "child_process";
41524
- import { mkdir as mkdir14, readFile as readFile21, rm as rm8 } from "fs/promises";
41525
- import path34 from "path";
42188
+ import { mkdir as mkdir14, readFile as readFile22, rm as rm8 } from "fs/promises";
42189
+ import path35 from "path";
41526
42190
  var SERVER_HERMES_RELEASES_LATEST_PATH = "/api/v1/hermes-agent/releases/latest";
41527
42191
  var RELEASE_CACHE_TTL_MS = 6 * 60 * 60 * 1e3;
41528
42192
  var RELEASE_FETCH_TIMEOUT_MS = 5e3;
@@ -41759,20 +42423,20 @@ function normalizeServerReleaseSnapshot(payload) {
41759
42423
  const remote = toNullableRecord(snapshot.remote);
41760
42424
  return {
41761
42425
  remote: remote ? normalizeServerRelease(remote) : null,
41762
- cacheState: readString26(snapshot, "cache_state") ?? readString26(snapshot, "cacheState"),
41763
- issue: readString26(snapshot, "issue")
42426
+ cacheState: readString27(snapshot, "cache_state") ?? readString27(snapshot, "cacheState"),
42427
+ issue: readString27(snapshot, "issue")
41764
42428
  };
41765
42429
  }
41766
42430
  function normalizeServerRelease(payload) {
41767
- const tag = readString26(payload, "tag");
41768
- const name = readString26(payload, "name");
42431
+ const tag = readString27(payload, "tag");
42432
+ const name = readString27(payload, "name");
41769
42433
  return {
41770
- version: readString26(payload, "version") ?? extractSemver(name) ?? extractTagSemver(tag),
42434
+ version: readString27(payload, "version") ?? extractSemver(name) ?? extractTagSemver(tag),
41771
42435
  tag,
41772
42436
  name,
41773
- releaseUrl: readString26(payload, "releaseUrl") ?? readString26(payload, "release_url"),
41774
- publishedAt: readString26(payload, "publishedAt") ?? readString26(payload, "published_at"),
41775
- fetchedAt: readString26(payload, "fetchedAt") ?? readString26(payload, "fetched_at") ?? (/* @__PURE__ */ new Date()).toISOString()
42437
+ releaseUrl: readString27(payload, "releaseUrl") ?? readString27(payload, "release_url"),
42438
+ publishedAt: readString27(payload, "publishedAt") ?? readString27(payload, "published_at"),
42439
+ fetchedAt: readString27(payload, "fetchedAt") ?? readString27(payload, "fetched_at") ?? (/* @__PURE__ */ new Date()).toISOString()
41776
42440
  };
41777
42441
  }
41778
42442
  async function readReleaseCache(paths) {
@@ -41791,7 +42455,7 @@ async function writeUpdateState(paths, state) {
41791
42455
  await writeJsonFile(updateStatePath(paths), state);
41792
42456
  }
41793
42457
  async function readUpdateLogLines(paths) {
41794
- const raw = await readFile21(updateLogPath(paths), "utf8").catch(() => "");
42458
+ const raw = await readFile22(updateLogPath(paths), "utf8").catch(() => "");
41795
42459
  if (!raw.trim()) {
41796
42460
  return [];
41797
42461
  }
@@ -41800,13 +42464,13 @@ async function readUpdateLogLines(paths) {
41800
42464
  );
41801
42465
  }
41802
42466
  function releaseCachePath(paths) {
41803
- return path34.join(paths.indexesDir, "hermes-release-check.json");
42467
+ return path35.join(paths.indexesDir, "hermes-release-check.json");
41804
42468
  }
41805
42469
  function updateStatePath(paths) {
41806
- return path34.join(paths.runDir, "hermes-update-state.json");
42470
+ return path35.join(paths.runDir, "hermes-update-state.json");
41807
42471
  }
41808
42472
  function updateLogPath(paths) {
41809
- return path34.join(paths.logsDir, UPDATE_LOG_FILE);
42473
+ return path35.join(paths.logsDir, UPDATE_LOG_FILE);
41810
42474
  }
41811
42475
  async function clearUpdateLogFiles(paths) {
41812
42476
  const primary = updateLogPath(paths);
@@ -41898,7 +42562,7 @@ function isRecentRunningState2(state) {
41898
42562
  const startedAt = Date.parse(state.started_at);
41899
42563
  return Number.isFinite(startedAt) && Date.now() - startedAt < 3e4;
41900
42564
  }
41901
- function readString26(payload, key) {
42565
+ function readString27(payload, key) {
41902
42566
  const value = payload[key];
41903
42567
  return typeof value === "string" && value.trim() ? value.trim() : null;
41904
42568
  }
@@ -41906,13 +42570,13 @@ function readString26(payload, key) {
41906
42570
  // src/link/updates.ts
41907
42571
  import { spawn as spawn6 } from "child_process";
41908
42572
  import { EventEmitter as EventEmitter4 } from "events";
41909
- import { mkdir as mkdir17, readFile as readFile23, rm as rm11 } from "fs/promises";
41910
- import path36 from "path";
42573
+ import { mkdir as mkdir17, readFile as readFile24, rm as rm11 } from "fs/promises";
42574
+ import path37 from "path";
41911
42575
 
41912
42576
  // src/daemon/process.ts
41913
42577
  import { spawn as spawn5 } from "child_process";
41914
- import { mkdir as mkdir16, readFile as readFile22, rm as rm10, writeFile as writeFile4 } from "fs/promises";
41915
- import path35 from "path";
42578
+ import { mkdir as mkdir16, readFile as readFile23, rm as rm10, writeFile as writeFile4 } from "fs/promises";
42579
+ import path36 from "path";
41916
42580
 
41917
42581
  // src/daemon/service.ts
41918
42582
  import { createServer } from "http";
@@ -43940,7 +44604,7 @@ async function runDaemonSupervisor(paths = resolveRuntimePaths()) {
43940
44604
  await mkdir16(paths.logsDir, { recursive: true, mode: 448 });
43941
44605
  const log = createRotatingTextLogWriter({
43942
44606
  paths,
43943
- fileName: path35.basename(daemonLogFile(paths))
44607
+ fileName: path36.basename(daemonLogFile(paths))
43944
44608
  });
43945
44609
  const scriptPath = currentCliScriptPath();
43946
44610
  const write = (chunk) => {
@@ -44120,7 +44784,7 @@ function currentCliScriptPath() {
44120
44784
  return process.argv[1];
44121
44785
  }
44122
44786
  async function readPid(filePath) {
44123
- const raw = await readFile22(filePath, "utf8").catch(() => null);
44787
+ const raw = await readFile23(filePath, "utf8").catch(() => null);
44124
44788
  if (!raw) {
44125
44789
  return null;
44126
44790
  }
@@ -44239,7 +44903,7 @@ function terminateChild(child, previousForceKillTimer) {
44239
44903
  }
44240
44904
  }
44241
44905
  function supervisorStopIntentPath(paths) {
44242
- return path35.join(paths.runDir, "supervisor-stop-intent.json");
44906
+ return path36.join(paths.runDir, "supervisor-stop-intent.json");
44243
44907
  }
44244
44908
  async function writeSupervisorStopIntent(paths, pid) {
44245
44909
  await mkdir16(paths.runDir, { recursive: true, mode: 448 });
@@ -44252,7 +44916,7 @@ async function writeSupervisorStopIntent(paths, pid) {
44252
44916
  }
44253
44917
  async function consumeSupervisorStopIntent(paths, pid) {
44254
44918
  const filePath = supervisorStopIntentPath(paths);
44255
- const raw = await readFile22(filePath, "utf8").catch(() => null);
44919
+ const raw = await readFile23(filePath, "utf8").catch(() => null);
44256
44920
  if (!raw) {
44257
44921
  return false;
44258
44922
  }
@@ -44270,7 +44934,7 @@ async function consumeSupervisorStopIntent(paths, pid) {
44270
44934
  }
44271
44935
  async function clearExpiredSupervisorStopIntent(paths) {
44272
44936
  const filePath = supervisorStopIntentPath(paths);
44273
- const raw = await readFile22(filePath, "utf8").catch(() => null);
44937
+ const raw = await readFile23(filePath, "utf8").catch(() => null);
44274
44938
  if (!raw) {
44275
44939
  return;
44276
44940
  }
@@ -44719,16 +45383,16 @@ function normalizeServerSnapshot(payload) {
44719
45383
  if (!policy) {
44720
45384
  return {
44721
45385
  remote: null,
44722
- issue: readString27(snapshot, "issue")
45386
+ issue: readString28(snapshot, "issue")
44723
45387
  };
44724
45388
  }
44725
45389
  const release = toNullableRecord2(snapshot.release);
44726
- const currentVersion = readString27(policy, "current_version") ?? readString27(policy, "currentVersion");
44727
- const minSafeVersion = readString27(policy, "min_safe_version") ?? readString27(policy, "minSafeVersion");
45390
+ const currentVersion = readString28(policy, "current_version") ?? readString28(policy, "currentVersion");
45391
+ const minSafeVersion = readString28(policy, "min_safe_version") ?? readString28(policy, "minSafeVersion");
44728
45392
  if (!currentVersion) {
44729
45393
  return {
44730
45394
  remote: null,
44731
- issue: readString27(snapshot, "issue")
45395
+ issue: readString28(snapshot, "issue")
44732
45396
  };
44733
45397
  }
44734
45398
  return {
@@ -44736,10 +45400,10 @@ function normalizeServerSnapshot(payload) {
44736
45400
  current_version: currentVersion,
44737
45401
  min_safe_version: minSafeVersion,
44738
45402
  target_version: currentVersion,
44739
- release_url: release ? readString27(release, "release_url") ?? readString27(release, "releaseUrl") : null,
44740
- published_at: release ? readString27(release, "published_at") ?? readString27(release, "publishedAt") : null
45403
+ release_url: release ? readString28(release, "release_url") ?? readString28(release, "releaseUrl") : null,
45404
+ published_at: release ? readString28(release, "published_at") ?? readString28(release, "publishedAt") : null
44741
45405
  },
44742
- issue: readString27(snapshot, "issue")
45406
+ issue: readString28(snapshot, "issue")
44743
45407
  };
44744
45408
  }
44745
45409
  async function fetchCurrentLinkReleaseFromServer(options, fetcher, channel) {
@@ -44802,7 +45466,7 @@ async function buildOfficialInstallCommand(options, targetVersion) {
44802
45466
  };
44803
45467
  }
44804
45468
  function buildUnixInstallCommand(installerUrl) {
44805
- const nodeBinDir = path36.dirname(process.execPath);
45469
+ const nodeBinDir = path37.dirname(process.execPath);
44806
45470
  const fetchScript = [
44807
45471
  quoteShellToken(process.execPath),
44808
45472
  "--input-type=module",
@@ -45063,7 +45727,7 @@ async function writeUpdateState2(paths, state) {
45063
45727
  await writeJsonFile(updateStatePath2(paths), state);
45064
45728
  }
45065
45729
  async function readUpdateLogLines2(paths) {
45066
- const raw = await readFile23(updateLogPath2(paths), "utf8").catch(() => "");
45730
+ const raw = await readFile24(updateLogPath2(paths), "utf8").catch(() => "");
45067
45731
  if (!raw.trim()) {
45068
45732
  return [];
45069
45733
  }
@@ -45072,10 +45736,10 @@ async function readUpdateLogLines2(paths) {
45072
45736
  );
45073
45737
  }
45074
45738
  function updateStatePath2(paths) {
45075
- return path36.join(paths.runDir, "link-update-state.json");
45739
+ return path37.join(paths.runDir, "link-update-state.json");
45076
45740
  }
45077
45741
  function updateLogPath2(paths) {
45078
- return path36.join(paths.logsDir, UPDATE_LOG_FILE2);
45742
+ return path37.join(paths.logsDir, UPDATE_LOG_FILE2);
45079
45743
  }
45080
45744
  async function clearUpdateLogFiles2(paths) {
45081
45745
  const primary = updateLogPath2(paths);
@@ -45153,13 +45817,13 @@ function toRecord26(value) {
45153
45817
  function toNullableRecord2(value) {
45154
45818
  return typeof value === "object" && value !== null ? value : null;
45155
45819
  }
45156
- function readString27(payload, key) {
45820
+ function readString28(payload, key) {
45157
45821
  const value = payload[key];
45158
45822
  return typeof value === "string" && value.trim() ? value.trim() : null;
45159
45823
  }
45160
45824
 
45161
45825
  // src/pairing/pairing.ts
45162
- import path37 from "path";
45826
+ import path38 from "path";
45163
45827
  import { rm as rm12 } from "fs/promises";
45164
45828
 
45165
45829
  // src/relay/bootstrap.ts
@@ -45499,10 +46163,10 @@ async function loadRequiredIdentity2(paths) {
45499
46163
  }
45500
46164
  return identity;
45501
46165
  }
45502
- async function postServerJson(serverBaseUrl, path38, body, options) {
46166
+ async function postServerJson(serverBaseUrl, path39, body, options) {
45503
46167
  let response;
45504
46168
  try {
45505
- response = await fetch(`${serverBaseUrl.replace(/\/+$/u, "")}${path38}`, {
46169
+ response = await fetch(`${serverBaseUrl.replace(/\/+$/u, "")}${path39}`, {
45506
46170
  method: "POST",
45507
46171
  headers: {
45508
46172
  accept: "application/json",
@@ -45550,10 +46214,10 @@ function pairingErrorSnapshot(stage, error) {
45550
46214
  occurred_at: (/* @__PURE__ */ new Date()).toISOString()
45551
46215
  };
45552
46216
  }
45553
- async function patchServerJson(serverBaseUrl, path38, token, body, options) {
46217
+ async function patchServerJson(serverBaseUrl, path39, token, body, options) {
45554
46218
  let response;
45555
46219
  try {
45556
- response = await fetch(`${serverBaseUrl.replace(/\/+$/u, "")}${path38}`, {
46220
+ response = await fetch(`${serverBaseUrl.replace(/\/+$/u, "")}${path39}`, {
45557
46221
  method: "PATCH",
45558
46222
  headers: {
45559
46223
  accept: "application/json",
@@ -45601,10 +46265,10 @@ function createPairingNetworkError(input) {
45601
46265
  );
45602
46266
  }
45603
46267
  function pairingClaimPath(sessionId, paths) {
45604
- return path37.join(paths.pairingDir, `${Buffer.from(sessionId).toString("base64url")}.claimed.json`);
46268
+ return path38.join(paths.pairingDir, `${Buffer.from(sessionId).toString("base64url")}.claimed.json`);
45605
46269
  }
45606
46270
  function pairingSessionPath(sessionId, paths) {
45607
- return path37.join(paths.pairingDir, `${Buffer.from(sessionId).toString("base64url")}.json`);
46271
+ return path38.join(paths.pairingDir, `${Buffer.from(sessionId).toString("base64url")}.json`);
45608
46272
  }
45609
46273
  function qrPreferredUrls(routes) {
45610
46274
  return routes.preferredUrls.filter((url) => !url.includes("/api/v1/relay/links/")).slice(0, 1);
@@ -45677,6 +46341,7 @@ function registerSystemRoutes(router, options) {
45677
46341
  conversation_delete: true,
45678
46342
  conversation_bulk_delete: true,
45679
46343
  conversation_clear_plan: true,
46344
+ conversation_categories: true,
45680
46345
  conversation_cancel: true,
45681
46346
  conversation_queue_controls: true,
45682
46347
  conversation_queue_limit: MAX_CONVERSATION_QUEUED_RUNS,
@@ -45707,8 +46372,8 @@ function registerSystemRoutes(router, options) {
45707
46372
  });
45708
46373
  router.post("/api/v1/pairing/claim", async (ctx) => {
45709
46374
  const body = await readJsonBody(ctx.req);
45710
- const sessionId = readString22(body, "session_id") ?? readString22(body, "sessionId");
45711
- const claimToken = readString22(body, "claim_token") ?? readString22(body, "claimToken");
46375
+ const sessionId = readString23(body, "session_id") ?? readString23(body, "sessionId");
46376
+ const claimToken = readString23(body, "claim_token") ?? readString23(body, "claimToken");
45712
46377
  if (!sessionId || !claimToken) {
45713
46378
  throw new LinkHttpError(
45714
46379
  400,
@@ -45719,10 +46384,10 @@ function registerSystemRoutes(router, options) {
45719
46384
  const claimed = await claimPairing({
45720
46385
  sessionId,
45721
46386
  claimToken,
45722
- deviceLabel: readString22(body, "device_label") ?? readString22(body, "deviceLabel") ?? "HermesPilot App",
45723
- devicePlatform: readString22(body, "device_platform") ?? readString22(body, "devicePlatform") ?? "unknown",
45724
- deviceModel: readString22(body, "device_model") ?? readString22(body, "deviceModel"),
45725
- appInstanceId: readString22(body, "app_instance_id") ?? readString22(body, "appInstanceId"),
46387
+ deviceLabel: readString23(body, "device_label") ?? readString23(body, "deviceLabel") ?? "HermesPilot App",
46388
+ devicePlatform: readString23(body, "device_platform") ?? readString23(body, "devicePlatform") ?? "unknown",
46389
+ deviceModel: readString23(body, "device_model") ?? readString23(body, "deviceModel"),
46390
+ appInstanceId: readString23(body, "app_instance_id") ?? readString23(body, "appInstanceId"),
45726
46391
  paths
45727
46392
  });
45728
46393
  ctx.body = claimed;
@@ -45802,9 +46467,9 @@ function registerSystemRoutes(router, options) {
45802
46467
  const body = await readJsonBody(ctx.req);
45803
46468
  const session = await createDeviceSession(
45804
46469
  {
45805
- label: readString22(body, "device_label") ?? readString22(body, "deviceLabel") ?? "HermesPilot App",
45806
- platform: readString22(body, "device_platform") ?? readString22(body, "devicePlatform") ?? "unknown",
45807
- model: readString22(body, "device_model") ?? readString22(body, "deviceModel"),
46470
+ label: readString23(body, "device_label") ?? readString23(body, "deviceLabel") ?? "HermesPilot App",
46471
+ platform: readString23(body, "device_platform") ?? readString23(body, "devicePlatform") ?? "unknown",
46472
+ model: readString23(body, "device_model") ?? readString23(body, "deviceModel"),
45808
46473
  appInstanceId: auth.appInstanceId
45809
46474
  },
45810
46475
  paths
@@ -45833,7 +46498,7 @@ function registerSystemRoutes(router, options) {
45833
46498
  });
45834
46499
  router.post("/api/v1/auth/refresh", async (ctx) => {
45835
46500
  const body = await readJsonBody(ctx.req);
45836
- const refreshToken = readString22(body, "refresh_token") ?? readString22(body, "refreshToken");
46501
+ const refreshToken = readString23(body, "refresh_token") ?? readString23(body, "refreshToken");
45837
46502
  if (!refreshToken) {
45838
46503
  throw new LinkHttpError(
45839
46504
  400,
@@ -45844,10 +46509,10 @@ function registerSystemRoutes(router, options) {
45844
46509
  const session = await refreshDeviceSession(
45845
46510
  refreshToken,
45846
46511
  {
45847
- appInstanceId: readString22(body, "app_instance_id") ?? readString22(body, "appInstanceId"),
45848
- label: readString22(body, "device_label") ?? readString22(body, "deviceLabel"),
45849
- platform: readString22(body, "device_platform") ?? readString22(body, "devicePlatform"),
45850
- model: readString22(body, "device_model") ?? readString22(body, "deviceModel")
46512
+ appInstanceId: readString23(body, "app_instance_id") ?? readString23(body, "appInstanceId"),
46513
+ label: readString23(body, "device_label") ?? readString23(body, "deviceLabel"),
46514
+ platform: readString23(body, "device_platform") ?? readString23(body, "devicePlatform"),
46515
+ model: readString23(body, "device_model") ?? readString23(body, "deviceModel")
45851
46516
  },
45852
46517
  paths
45853
46518
  );
@@ -45866,7 +46531,7 @@ function registerSystemRoutes(router, options) {
45866
46531
  });
45867
46532
  router.post("/api/v1/auth/logout", async (ctx) => {
45868
46533
  const body = await readJsonBody(ctx.req);
45869
- const refreshToken = readString22(body, "refresh_token") ?? readString22(body, "refreshToken");
46534
+ const refreshToken = readString23(body, "refresh_token") ?? readString23(body, "refreshToken");
45870
46535
  if (refreshToken) {
45871
46536
  await revokeDeviceRefreshToken(refreshToken, paths);
45872
46537
  }
@@ -46107,7 +46772,7 @@ function registerSystemRoutes(router, options) {
46107
46772
  router.patch("/api/v1/devices/:deviceId", async (ctx) => {
46108
46773
  const auth = await authenticateRequest(ctx, paths);
46109
46774
  const body = await readJsonBody(ctx.req);
46110
- const label = readString22(body, "label") ?? readString22(body, "device_label");
46775
+ const label = readString23(body, "label") ?? readString23(body, "device_label");
46111
46776
  if (!label) {
46112
46777
  throw new LinkHttpError(
46113
46778
  400,
@@ -46151,7 +46816,7 @@ function isActiveCronJob(job) {
46151
46816
  if (!enabled) {
46152
46817
  return false;
46153
46818
  }
46154
- const state = readString22(job, "state")?.toLowerCase();
46819
+ const state = readString23(job, "state")?.toLowerCase();
46155
46820
  return !["paused", "disabled", "completed", "deleted"].includes(state ?? "");
46156
46821
  }
46157
46822
  function filterLogsWithinHours(logs, hours, now = Date.now()) {
@@ -46195,8 +46860,8 @@ function registerWorkspaceRoutes(router, options) {
46195
46860
  ctx.body = {
46196
46861
  ok: true,
46197
46862
  workspace: await conversations.createWorkspace({
46198
- name: readString22(body, "name") ?? "",
46199
- icon: readString22(body, "icon") ?? void 0
46863
+ name: readString23(body, "name") ?? "",
46864
+ icon: readString23(body, "icon") ?? void 0
46200
46865
  })
46201
46866
  };
46202
46867
  });
@@ -46206,8 +46871,8 @@ function registerWorkspaceRoutes(router, options) {
46206
46871
  ctx.body = {
46207
46872
  ok: true,
46208
46873
  workspace: await conversations.renameWorkspace(ctx.params.workspaceId, {
46209
- name: readString22(body, "name") ?? "",
46210
- icon: readString22(body, "icon") ?? void 0
46874
+ name: readString23(body, "name") ?? "",
46875
+ icon: readString23(body, "icon") ?? void 0
46211
46876
  })
46212
46877
  };
46213
46878
  });
@@ -46290,8 +46955,8 @@ function registerLinkUpdateRoutes(router, options) {
46290
46955
  ctx.body = await startLinkUpdate({
46291
46956
  paths,
46292
46957
  logger,
46293
- channel: readString22(body, "channel"),
46294
- targetVersion: readString22(body, "target_version") ?? readString22(body, "targetVersion")
46958
+ channel: readString23(body, "channel"),
46959
+ targetVersion: readString23(body, "target_version") ?? readString23(body, "targetVersion")
46295
46960
  });
46296
46961
  });
46297
46962
  router.get("/api/v1/link/update/events", async (ctx) => {
@@ -46321,7 +46986,7 @@ import QRCode from "qrcode";
46321
46986
  function registerPairingRoutes(router, options) {
46322
46987
  const { paths } = options;
46323
46988
  router.get("/pair", async (ctx) => {
46324
- const sessionId = readString22(ctx.query, "session_id");
46989
+ const sessionId = readString23(ctx.query, "session_id");
46325
46990
  if (!sessionId) {
46326
46991
  throw new LinkHttpError(400, "pairing_session_required", "session_id is required");
46327
46992
  }
@@ -46346,7 +47011,7 @@ function registerPairingRoutes(router, options) {
46346
47011
  ctx.body = page;
46347
47012
  });
46348
47013
  router.get("/api/v1/pairing/session", async (ctx) => {
46349
- const sessionId = readString22(ctx.query, "session_id");
47014
+ const sessionId = readString23(ctx.query, "session_id");
46350
47015
  if (!sessionId) {
46351
47016
  throw new LinkHttpError(400, "pairing_session_required", "session_id is required");
46352
47017
  }
@@ -46816,7 +47481,7 @@ function registerInternalRoutes(router, options) {
46816
47481
  router.post("/internal/deliver", async (ctx) => {
46817
47482
  assertLoopbackRequest(ctx.req);
46818
47483
  const body = await readJsonBody(ctx.req);
46819
- const stagingDir = readString22(body, "staging_dir") ?? readString22(body, "stagingDir");
47484
+ const stagingDir = readString23(body, "staging_dir") ?? readString23(body, "stagingDir");
46820
47485
  if (!stagingDir) {
46821
47486
  throw new LinkHttpError(
46822
47487
  400,
@@ -46835,9 +47500,9 @@ function registerInternalRoutes(router, options) {
46835
47500
  ctx.body = {
46836
47501
  ok: true,
46837
47502
  ...await options.conversations.deliverFilesFromTool({
46838
- profile: readString22(body, "profile") ?? readString22(body, "profile_name") ?? readString22(body, "profileName") ?? void 0,
46839
- taskId: readString22(body, "task_id") ?? readString22(body, "taskId") ?? void 0,
46840
- sessionId: readString22(body, "session_id") ?? readString22(body, "sessionId") ?? void 0,
47503
+ profile: readString23(body, "profile") ?? readString23(body, "profile_name") ?? readString23(body, "profileName") ?? void 0,
47504
+ taskId: readString23(body, "task_id") ?? readString23(body, "taskId") ?? void 0,
47505
+ sessionId: readString23(body, "session_id") ?? readString23(body, "sessionId") ?? void 0,
46841
47506
  files: body.files ?? body.file ?? body.path
46842
47507
  })
46843
47508
  };
@@ -46898,9 +47563,9 @@ function registerLiveActivityRoutes(router, options) {
46898
47563
  const auth = await authenticateRequest(ctx, paths);
46899
47564
  const body = await readJsonBody(ctx.req);
46900
47565
  const targetKind = readTargetKind(body);
46901
- const runId = normalizePattern(readString22(body, "run_id") ?? readString22(body, "runId"), RUN_ID_PATTERN);
47566
+ const runId = normalizePattern(readString23(body, "run_id") ?? readString23(body, "runId"), RUN_ID_PATTERN);
46902
47567
  const operationId = normalizePattern(
46903
- readString22(body, "operation_id") ?? readString22(body, "operationId"),
47568
+ readString23(body, "operation_id") ?? readString23(body, "operationId"),
46904
47569
  OPERATION_ID_PATTERN
46905
47570
  );
46906
47571
  if (targetKind === "run" && !runId) {
@@ -46946,7 +47611,7 @@ function registerLiveActivityRoutes(router, options) {
46946
47611
  });
46947
47612
  }
46948
47613
  function readTargetKind(body) {
46949
- const value = readString22(body, "target_kind") ?? readString22(body, "targetKind");
47614
+ const value = readString23(body, "target_kind") ?? readString23(body, "targetKind");
46950
47615
  return readTargetKindValue(value);
46951
47616
  }
46952
47617
  function readTargetKindValue(value) {
@@ -46968,21 +47633,21 @@ function readQueryValue(query, key) {
46968
47633
  return readQueryString(query[key]) ?? null;
46969
47634
  }
46970
47635
  function readApnsEnvironment(body) {
46971
- const value = readString22(body, "apns_environment") ?? readString22(body, "apnsEnvironment");
47636
+ const value = readString23(body, "apns_environment") ?? readString23(body, "apnsEnvironment");
46972
47637
  if (value === "sandbox" || value === "production") {
46973
47638
  return value;
46974
47639
  }
46975
47640
  throw new LinkHttpError(400, "apns_environment_invalid", "apns_environment must be sandbox or production");
46976
47641
  }
46977
47642
  function readLanguage2(body) {
46978
- const value = readString22(body, "language") ?? readString22(body, "preferred_language") ?? readString22(body, "preferredLanguage");
47643
+ const value = readString23(body, "language") ?? readString23(body, "preferred_language") ?? readString23(body, "preferredLanguage");
46979
47644
  if (!value) {
46980
47645
  return null;
46981
47646
  }
46982
47647
  return value.toLowerCase().startsWith("zh") ? "zh" : "en";
46983
47648
  }
46984
47649
  function readPrivacyLevel(body) {
46985
- const value = readString22(body, "privacy_level") ?? readString22(body, "privacyLevel");
47650
+ const value = readString23(body, "privacy_level") ?? readString23(body, "privacyLevel");
46986
47651
  if (value === "minimal" || value === "detailed") {
46987
47652
  return value;
46988
47653
  }
@@ -46990,7 +47655,7 @@ function readPrivacyLevel(body) {
46990
47655
  }
46991
47656
  function readRequiredString(body, keys, code) {
46992
47657
  for (const key of keys) {
46993
- const value = readString22(body, key);
47658
+ const value = readString23(body, key);
46994
47659
  if (value) {
46995
47660
  return value;
46996
47661
  }
@@ -47006,7 +47671,7 @@ function readRequiredPattern(body, keys, pattern, code) {
47006
47671
  }
47007
47672
  function readOptionalString2(body, keys, maxLength) {
47008
47673
  for (const key of keys) {
47009
- const value = readString22(body, key);
47674
+ const value = readString23(body, key);
47010
47675
  if (value) {
47011
47676
  return value.slice(0, maxLength);
47012
47677
  }
@@ -47018,7 +47683,7 @@ function normalizePattern(value, pattern) {
47018
47683
  }
47019
47684
  function readIso(body, keys) {
47020
47685
  for (const key of keys) {
47021
- const value = readString22(body, key);
47686
+ const value = readString23(body, key);
47022
47687
  if (!value) {
47023
47688
  continue;
47024
47689
  }