adhdev 0.8.94 → 0.8.95

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -4661,6 +4661,125 @@ function listSavedHistorySessions(agentType, options = {}) {
4661
4661
  return { sessions: [], hasMore: false };
4662
4662
  }
4663
4663
  }
4664
+ function normalizeCanonicalHermesMessageContent(content) {
4665
+ if (typeof content === "string") return content.trim();
4666
+ if (content == null) return "";
4667
+ try {
4668
+ return JSON.stringify(content).trim();
4669
+ } catch {
4670
+ return String(content).trim();
4671
+ }
4672
+ }
4673
+ function extractCanonicalHermesMessageTimestamp(message, fallbackTs) {
4674
+ const numericTimestamp = Number(message.receivedAt || message.timestamp || message.ts || 0);
4675
+ if (Number.isFinite(numericTimestamp) && numericTimestamp > 0) return numericTimestamp;
4676
+ const stringTimestamp = typeof message.ts === "string" ? Date.parse(message.ts) : typeof message.timestamp === "string" ? Date.parse(message.timestamp) : NaN;
4677
+ if (Number.isFinite(stringTimestamp) && stringTimestamp > 0) return stringTimestamp;
4678
+ return fallbackTs;
4679
+ }
4680
+ function readExistingHermesSessionStartRecord(historySessionId) {
4681
+ try {
4682
+ const dir = path7.join(HISTORY_DIR, "hermes-cli");
4683
+ if (!fs3.existsSync(dir)) return null;
4684
+ const files = listHistoryFiles(dir, historySessionId).sort();
4685
+ for (const file2 of files) {
4686
+ const lines = fs3.readFileSync(path7.join(dir, file2), "utf-8").split("\n").filter(Boolean);
4687
+ for (const line of lines) {
4688
+ try {
4689
+ const parsed = JSON.parse(line);
4690
+ if (parsed.historySessionId !== historySessionId) continue;
4691
+ if (parsed.kind === "session_start" && parsed.role === "system") {
4692
+ return parsed;
4693
+ }
4694
+ } catch {
4695
+ }
4696
+ }
4697
+ }
4698
+ return null;
4699
+ } catch {
4700
+ return null;
4701
+ }
4702
+ }
4703
+ function rebuildHermesSavedHistoryFromCanonicalSession(historySessionId) {
4704
+ const normalizedSessionId = normalizeSavedHistorySessionId("hermes-cli", historySessionId);
4705
+ if (!normalizedSessionId) return false;
4706
+ try {
4707
+ const sessionFilePath = path7.join(os6.homedir(), ".hermes", "sessions", `session_${normalizedSessionId}.json`);
4708
+ if (!fs3.existsSync(sessionFilePath)) return false;
4709
+ const raw = JSON.parse(fs3.readFileSync(sessionFilePath, "utf-8"));
4710
+ const canonicalMessages = Array.isArray(raw.messages) ? raw.messages : [];
4711
+ const dir = path7.join(HISTORY_DIR, "hermes-cli");
4712
+ fs3.mkdirSync(dir, { recursive: true });
4713
+ const existingSessionStart = readExistingHermesSessionStartRecord(normalizedSessionId);
4714
+ const records = [];
4715
+ if (existingSessionStart) {
4716
+ records.push({
4717
+ ...existingSessionStart,
4718
+ historySessionId: normalizedSessionId
4719
+ });
4720
+ }
4721
+ let fallbackTs = Date.parse(raw.session_start || raw.last_updated || "") || Date.now();
4722
+ for (const message of canonicalMessages) {
4723
+ const role = String(message.role || "").trim();
4724
+ const content = normalizeCanonicalHermesMessageContent(message.content);
4725
+ if (!content) continue;
4726
+ const receivedAt = extractCanonicalHermesMessageTimestamp(message, fallbackTs);
4727
+ fallbackTs = receivedAt + 1;
4728
+ if (role === "user") {
4729
+ records.push({
4730
+ ts: new Date(receivedAt).toISOString(),
4731
+ receivedAt,
4732
+ role: "user",
4733
+ content,
4734
+ kind: "standard",
4735
+ agent: "hermes-cli",
4736
+ historySessionId: normalizedSessionId
4737
+ });
4738
+ continue;
4739
+ }
4740
+ if (role === "assistant") {
4741
+ records.push({
4742
+ ts: new Date(receivedAt).toISOString(),
4743
+ receivedAt,
4744
+ role: "assistant",
4745
+ content,
4746
+ kind: "standard",
4747
+ agent: "hermes-cli",
4748
+ historySessionId: normalizedSessionId
4749
+ });
4750
+ continue;
4751
+ }
4752
+ if (role === "tool") {
4753
+ records.push({
4754
+ ts: new Date(receivedAt).toISOString(),
4755
+ receivedAt,
4756
+ role: "assistant",
4757
+ content,
4758
+ kind: "tool",
4759
+ senderName: "Tool",
4760
+ agent: "hermes-cli",
4761
+ historySessionId: normalizedSessionId
4762
+ });
4763
+ }
4764
+ }
4765
+ if (records.length === 0) return false;
4766
+ const prefix = `${normalizedSessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
4767
+ for (const file2 of fs3.readdirSync(dir)) {
4768
+ if (file2.startsWith(prefix) && file2.endsWith(".jsonl")) {
4769
+ fs3.unlinkSync(path7.join(dir, file2));
4770
+ }
4771
+ }
4772
+ const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
4773
+ const filePath = path7.join(dir, `${prefix}${targetDate}.jsonl`);
4774
+ fs3.writeFileSync(filePath, `${records.map((record2) => JSON.stringify(record2)).join("\n")}
4775
+ `, "utf-8");
4776
+ invalidatePersistedSavedHistoryIndex("hermes-cli", dir);
4777
+ savedHistorySessionCache.delete("hermes-cli");
4778
+ return true;
4779
+ } catch {
4780
+ return false;
4781
+ }
4782
+ }
4664
4783
  var fs3, path7, os6, HISTORY_DIR, RETAIN_DAYS, SAVED_HISTORY_INDEX_VERSION, SAVED_HISTORY_INDEX_FILE, SAVED_HISTORY_INDEX_LOCK_SUFFIX, SAVED_HISTORY_INDEX_LOCK_WAIT_MS, SAVED_HISTORY_INDEX_LOCK_STALE_MS, SAVED_HISTORY_INDEX_LOCK_POLL_MS, SAVED_HISTORY_ROLLUP_THRESHOLD_BYTES, savedHistorySessionCache, savedHistoryFileSummaryCache, savedHistoryBackgroundRefresh, savedHistoryRollupInFlight, CODEX_STARTER_PROMPT_RE, ChatHistoryWriter;
4665
4784
  var init_chat_history = __esm({
4666
4785
  "../../oss/packages/daemon-core/src/config/chat-history.ts"() {
@@ -14354,6 +14473,7 @@ var init_cli_provider_instance = __esm({
14354
14473
  historyWriter;
14355
14474
  runtimeMessages = [];
14356
14475
  lastPersistedHistoryMessages = [];
14476
+ lastCanonicalHermesSyncMtimeMs = 0;
14357
14477
  instanceId;
14358
14478
  suppressIdleHistoryReplay = false;
14359
14479
  errorMessage = void 0;
@@ -14386,34 +14506,7 @@ var init_cli_provider_instance = __esm({
14386
14506
  await this.enforceFreshSessionLaunchIfNeeded();
14387
14507
  this.maybeAppendRuntimeRecoveryMessage(this.adapter.getRuntimeMetadata());
14388
14508
  if (this.providerSessionId) {
14389
- this.historyWriter.compactHistorySession(this.type, this.providerSessionId);
14390
- const restoredHistory = readChatHistory(this.type, 0, 200, this.providerSessionId);
14391
- this.historyWriter.seedSessionHistory(
14392
- this.type,
14393
- restoredHistory.messages,
14394
- this.providerSessionId,
14395
- this.instanceId
14396
- );
14397
- this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
14398
- role: message.role,
14399
- content: message.content,
14400
- kind: message.kind,
14401
- senderName: message.senderName,
14402
- receivedAt: message.receivedAt
14403
- }));
14404
- this.suppressIdleHistoryReplay = restoredHistory.messages.length > 0;
14405
- if (restoredHistory.messages.length > 0) {
14406
- this.adapter.seedCommittedMessages(
14407
- restoredHistory.messages.map((message) => ({
14408
- role: message.role,
14409
- content: message.content,
14410
- timestamp: message.receivedAt,
14411
- receivedAt: message.receivedAt,
14412
- kind: message.kind,
14413
- senderName: message.senderName
14414
- }))
14415
- );
14416
- }
14509
+ this.restorePersistedHistoryFromCurrentSession();
14417
14510
  }
14418
14511
  if (this.providerSessionId && this.launchMode === "resume") {
14419
14512
  const resumedAt = Date.now();
@@ -14522,6 +14615,7 @@ var init_cli_provider_instance = __esm({
14522
14615
  parsedMessages = historyMessageCount > 0 ? parsedMessages.slice(-historyMessageCount) : [];
14523
14616
  }
14524
14617
  const mergedMessages = this.mergeConversationMessages(parsedMessages);
14618
+ const canonicalHermesBackedHistory = this.syncCanonicalHermesSavedHistoryIfNeeded();
14525
14619
  const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
14526
14620
  if (parsedMessages.length > 0) {
14527
14621
  const shouldSkipReplayPersist = this.suppressIdleHistoryReplay && adapterStatus.status === "idle" && parsedStatus?.status === "idle";
@@ -14539,7 +14633,7 @@ var init_cli_provider_instance = __esm({
14539
14633
  senderName: typeof message.senderName === "string" ? message.senderName : void 0,
14540
14634
  receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
14541
14635
  }));
14542
- if (!shouldSkipReplayPersist && normalizedMessagesToSave.length > 0) {
14636
+ if (!canonicalHermesBackedHistory && !shouldSkipReplayPersist && normalizedMessagesToSave.length > 0) {
14543
14637
  const incrementalMessages = buildIncrementalHistoryAppendMessages(this.lastPersistedHistoryMessages, normalizedMessagesToSave);
14544
14638
  this.historyWriter.appendNewMessages(
14545
14639
  this.type,
@@ -14549,7 +14643,9 @@ var init_cli_provider_instance = __esm({
14549
14643
  this.providerSessionId
14550
14644
  );
14551
14645
  }
14552
- this.lastPersistedHistoryMessages = normalizedMessagesToSave;
14646
+ if (!canonicalHermesBackedHistory) {
14647
+ this.lastPersistedHistoryMessages = normalizedMessagesToSave;
14648
+ }
14553
14649
  }
14554
14650
  this.applyProviderResponse(parsedStatus, { phase: "immediate" });
14555
14651
  const surface = resolveProviderStateSurface({
@@ -15006,6 +15102,7 @@ ${effect.notification.body || ""}`.trim();
15006
15102
  this.providerSessionId = nextSessionId;
15007
15103
  this.historyWriter.promoteHistorySession(this.type, previousHistorySessionId, nextSessionId);
15008
15104
  this.historyWriter.writeSessionStart(this.type, nextSessionId, this.workingDir, this.instanceId);
15105
+ this.restorePersistedHistoryFromCurrentSession();
15009
15106
  this.adapter.updateRuntimeMeta({ providerSessionId: nextSessionId });
15010
15107
  this.onProviderSessionResolved?.({
15011
15108
  instanceId: this.instanceId,
@@ -15017,6 +15114,61 @@ ${effect.notification.body || ""}`.trim();
15017
15114
  });
15018
15115
  LOG.info("CLI", `[${this.type}] discovered provider session id: ${nextSessionId}`);
15019
15116
  }
15117
+ syncCanonicalHermesSavedHistoryIfNeeded() {
15118
+ if (this.type !== "hermes-cli" || !this.providerSessionId) return false;
15119
+ try {
15120
+ const canonicalPath = path12.join(os14.homedir(), ".hermes", "sessions", `session_${this.providerSessionId}.json`);
15121
+ if (!fs5.existsSync(canonicalPath)) return false;
15122
+ const stat4 = fs5.statSync(canonicalPath);
15123
+ if (stat4.mtimeMs <= this.lastCanonicalHermesSyncMtimeMs) return true;
15124
+ const rebuilt = rebuildHermesSavedHistoryFromCanonicalSession(this.providerSessionId);
15125
+ if (!rebuilt) return false;
15126
+ this.lastCanonicalHermesSyncMtimeMs = stat4.mtimeMs;
15127
+ const restoredHistory = readChatHistory(this.type, 0, 200, this.providerSessionId);
15128
+ this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
15129
+ role: message.role,
15130
+ content: message.content,
15131
+ kind: message.kind,
15132
+ senderName: message.senderName,
15133
+ receivedAt: message.receivedAt
15134
+ }));
15135
+ return true;
15136
+ } catch {
15137
+ return false;
15138
+ }
15139
+ }
15140
+ restorePersistedHistoryFromCurrentSession() {
15141
+ if (!this.providerSessionId) return;
15142
+ this.syncCanonicalHermesSavedHistoryIfNeeded();
15143
+ this.historyWriter.compactHistorySession(this.type, this.providerSessionId);
15144
+ const restoredHistory = readChatHistory(this.type, 0, 200, this.providerSessionId);
15145
+ this.historyWriter.seedSessionHistory(
15146
+ this.type,
15147
+ restoredHistory.messages,
15148
+ this.providerSessionId,
15149
+ this.instanceId
15150
+ );
15151
+ this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
15152
+ role: message.role,
15153
+ content: message.content,
15154
+ kind: message.kind,
15155
+ senderName: message.senderName,
15156
+ receivedAt: message.receivedAt
15157
+ }));
15158
+ this.suppressIdleHistoryReplay = restoredHistory.messages.length > 0;
15159
+ if (restoredHistory.messages.length > 0) {
15160
+ this.adapter.seedCommittedMessages(
15161
+ restoredHistory.messages.map((message) => ({
15162
+ role: message.role,
15163
+ content: message.content,
15164
+ timestamp: message.receivedAt,
15165
+ receivedAt: message.receivedAt,
15166
+ kind: message.kind,
15167
+ senderName: message.senderName
15168
+ }))
15169
+ );
15170
+ }
15171
+ }
15020
15172
  getProbeDirectories() {
15021
15173
  const dirs = /* @__PURE__ */ new Set();
15022
15174
  const addDir = (value) => {
@@ -86650,7 +86802,7 @@ var init_adhdev_daemon = __esm({
86650
86802
  init_version();
86651
86803
  init_src();
86652
86804
  init_runtime_defaults();
86653
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.94" });
86805
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.95" });
86654
86806
  AdhdevDaemon = class _AdhdevDaemon {
86655
86807
  localHttpServer = null;
86656
86808
  localWss = null;