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/index.js CHANGED
@@ -4141,6 +4141,125 @@ function listSavedHistorySessions(agentType, options = {}) {
4141
4141
  return { sessions: [], hasMore: false };
4142
4142
  }
4143
4143
  }
4144
+ function normalizeCanonicalHermesMessageContent(content) {
4145
+ if (typeof content === "string") return content.trim();
4146
+ if (content == null) return "";
4147
+ try {
4148
+ return JSON.stringify(content).trim();
4149
+ } catch {
4150
+ return String(content).trim();
4151
+ }
4152
+ }
4153
+ function extractCanonicalHermesMessageTimestamp(message, fallbackTs) {
4154
+ const numericTimestamp = Number(message.receivedAt || message.timestamp || message.ts || 0);
4155
+ if (Number.isFinite(numericTimestamp) && numericTimestamp > 0) return numericTimestamp;
4156
+ const stringTimestamp = typeof message.ts === "string" ? Date.parse(message.ts) : typeof message.timestamp === "string" ? Date.parse(message.timestamp) : NaN;
4157
+ if (Number.isFinite(stringTimestamp) && stringTimestamp > 0) return stringTimestamp;
4158
+ return fallbackTs;
4159
+ }
4160
+ function readExistingHermesSessionStartRecord(historySessionId) {
4161
+ try {
4162
+ const dir = path7.join(HISTORY_DIR, "hermes-cli");
4163
+ if (!fs3.existsSync(dir)) return null;
4164
+ const files = listHistoryFiles(dir, historySessionId).sort();
4165
+ for (const file2 of files) {
4166
+ const lines = fs3.readFileSync(path7.join(dir, file2), "utf-8").split("\n").filter(Boolean);
4167
+ for (const line of lines) {
4168
+ try {
4169
+ const parsed = JSON.parse(line);
4170
+ if (parsed.historySessionId !== historySessionId) continue;
4171
+ if (parsed.kind === "session_start" && parsed.role === "system") {
4172
+ return parsed;
4173
+ }
4174
+ } catch {
4175
+ }
4176
+ }
4177
+ }
4178
+ return null;
4179
+ } catch {
4180
+ return null;
4181
+ }
4182
+ }
4183
+ function rebuildHermesSavedHistoryFromCanonicalSession(historySessionId) {
4184
+ const normalizedSessionId = normalizeSavedHistorySessionId("hermes-cli", historySessionId);
4185
+ if (!normalizedSessionId) return false;
4186
+ try {
4187
+ const sessionFilePath = path7.join(os5.homedir(), ".hermes", "sessions", `session_${normalizedSessionId}.json`);
4188
+ if (!fs3.existsSync(sessionFilePath)) return false;
4189
+ const raw = JSON.parse(fs3.readFileSync(sessionFilePath, "utf-8"));
4190
+ const canonicalMessages = Array.isArray(raw.messages) ? raw.messages : [];
4191
+ const dir = path7.join(HISTORY_DIR, "hermes-cli");
4192
+ fs3.mkdirSync(dir, { recursive: true });
4193
+ const existingSessionStart = readExistingHermesSessionStartRecord(normalizedSessionId);
4194
+ const records = [];
4195
+ if (existingSessionStart) {
4196
+ records.push({
4197
+ ...existingSessionStart,
4198
+ historySessionId: normalizedSessionId
4199
+ });
4200
+ }
4201
+ let fallbackTs = Date.parse(raw.session_start || raw.last_updated || "") || Date.now();
4202
+ for (const message of canonicalMessages) {
4203
+ const role = String(message.role || "").trim();
4204
+ const content = normalizeCanonicalHermesMessageContent(message.content);
4205
+ if (!content) continue;
4206
+ const receivedAt = extractCanonicalHermesMessageTimestamp(message, fallbackTs);
4207
+ fallbackTs = receivedAt + 1;
4208
+ if (role === "user") {
4209
+ records.push({
4210
+ ts: new Date(receivedAt).toISOString(),
4211
+ receivedAt,
4212
+ role: "user",
4213
+ content,
4214
+ kind: "standard",
4215
+ agent: "hermes-cli",
4216
+ historySessionId: normalizedSessionId
4217
+ });
4218
+ continue;
4219
+ }
4220
+ if (role === "assistant") {
4221
+ records.push({
4222
+ ts: new Date(receivedAt).toISOString(),
4223
+ receivedAt,
4224
+ role: "assistant",
4225
+ content,
4226
+ kind: "standard",
4227
+ agent: "hermes-cli",
4228
+ historySessionId: normalizedSessionId
4229
+ });
4230
+ continue;
4231
+ }
4232
+ if (role === "tool") {
4233
+ records.push({
4234
+ ts: new Date(receivedAt).toISOString(),
4235
+ receivedAt,
4236
+ role: "assistant",
4237
+ content,
4238
+ kind: "tool",
4239
+ senderName: "Tool",
4240
+ agent: "hermes-cli",
4241
+ historySessionId: normalizedSessionId
4242
+ });
4243
+ }
4244
+ }
4245
+ if (records.length === 0) return false;
4246
+ const prefix = `${normalizedSessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
4247
+ for (const file2 of fs3.readdirSync(dir)) {
4248
+ if (file2.startsWith(prefix) && file2.endsWith(".jsonl")) {
4249
+ fs3.unlinkSync(path7.join(dir, file2));
4250
+ }
4251
+ }
4252
+ const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
4253
+ const filePath = path7.join(dir, `${prefix}${targetDate}.jsonl`);
4254
+ fs3.writeFileSync(filePath, `${records.map((record2) => JSON.stringify(record2)).join("\n")}
4255
+ `, "utf-8");
4256
+ invalidatePersistedSavedHistoryIndex("hermes-cli", dir);
4257
+ savedHistorySessionCache.delete("hermes-cli");
4258
+ return true;
4259
+ } catch {
4260
+ return false;
4261
+ }
4262
+ }
4144
4263
  var fs3, path7, os5, 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;
4145
4264
  var init_chat_history = __esm({
4146
4265
  "../../oss/packages/daemon-core/src/config/chat-history.ts"() {
@@ -13413,6 +13532,7 @@ var init_cli_provider_instance = __esm({
13413
13532
  historyWriter;
13414
13533
  runtimeMessages = [];
13415
13534
  lastPersistedHistoryMessages = [];
13535
+ lastCanonicalHermesSyncMtimeMs = 0;
13416
13536
  instanceId;
13417
13537
  suppressIdleHistoryReplay = false;
13418
13538
  errorMessage = void 0;
@@ -13445,34 +13565,7 @@ var init_cli_provider_instance = __esm({
13445
13565
  await this.enforceFreshSessionLaunchIfNeeded();
13446
13566
  this.maybeAppendRuntimeRecoveryMessage(this.adapter.getRuntimeMetadata());
13447
13567
  if (this.providerSessionId) {
13448
- this.historyWriter.compactHistorySession(this.type, this.providerSessionId);
13449
- const restoredHistory = readChatHistory(this.type, 0, 200, this.providerSessionId);
13450
- this.historyWriter.seedSessionHistory(
13451
- this.type,
13452
- restoredHistory.messages,
13453
- this.providerSessionId,
13454
- this.instanceId
13455
- );
13456
- this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
13457
- role: message.role,
13458
- content: message.content,
13459
- kind: message.kind,
13460
- senderName: message.senderName,
13461
- receivedAt: message.receivedAt
13462
- }));
13463
- this.suppressIdleHistoryReplay = restoredHistory.messages.length > 0;
13464
- if (restoredHistory.messages.length > 0) {
13465
- this.adapter.seedCommittedMessages(
13466
- restoredHistory.messages.map((message) => ({
13467
- role: message.role,
13468
- content: message.content,
13469
- timestamp: message.receivedAt,
13470
- receivedAt: message.receivedAt,
13471
- kind: message.kind,
13472
- senderName: message.senderName
13473
- }))
13474
- );
13475
- }
13568
+ this.restorePersistedHistoryFromCurrentSession();
13476
13569
  }
13477
13570
  if (this.providerSessionId && this.launchMode === "resume") {
13478
13571
  const resumedAt = Date.now();
@@ -13581,6 +13674,7 @@ var init_cli_provider_instance = __esm({
13581
13674
  parsedMessages = historyMessageCount > 0 ? parsedMessages.slice(-historyMessageCount) : [];
13582
13675
  }
13583
13676
  const mergedMessages = this.mergeConversationMessages(parsedMessages);
13677
+ const canonicalHermesBackedHistory = this.syncCanonicalHermesSavedHistoryIfNeeded();
13584
13678
  const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
13585
13679
  if (parsedMessages.length > 0) {
13586
13680
  const shouldSkipReplayPersist = this.suppressIdleHistoryReplay && adapterStatus.status === "idle" && parsedStatus?.status === "idle";
@@ -13598,7 +13692,7 @@ var init_cli_provider_instance = __esm({
13598
13692
  senderName: typeof message.senderName === "string" ? message.senderName : void 0,
13599
13693
  receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
13600
13694
  }));
13601
- if (!shouldSkipReplayPersist && normalizedMessagesToSave.length > 0) {
13695
+ if (!canonicalHermesBackedHistory && !shouldSkipReplayPersist && normalizedMessagesToSave.length > 0) {
13602
13696
  const incrementalMessages = buildIncrementalHistoryAppendMessages(this.lastPersistedHistoryMessages, normalizedMessagesToSave);
13603
13697
  this.historyWriter.appendNewMessages(
13604
13698
  this.type,
@@ -13608,7 +13702,9 @@ var init_cli_provider_instance = __esm({
13608
13702
  this.providerSessionId
13609
13703
  );
13610
13704
  }
13611
- this.lastPersistedHistoryMessages = normalizedMessagesToSave;
13705
+ if (!canonicalHermesBackedHistory) {
13706
+ this.lastPersistedHistoryMessages = normalizedMessagesToSave;
13707
+ }
13612
13708
  }
13613
13709
  this.applyProviderResponse(parsedStatus, { phase: "immediate" });
13614
13710
  const surface = resolveProviderStateSurface({
@@ -14065,6 +14161,7 @@ ${effect.notification.body || ""}`.trim();
14065
14161
  this.providerSessionId = nextSessionId;
14066
14162
  this.historyWriter.promoteHistorySession(this.type, previousHistorySessionId, nextSessionId);
14067
14163
  this.historyWriter.writeSessionStart(this.type, nextSessionId, this.workingDir, this.instanceId);
14164
+ this.restorePersistedHistoryFromCurrentSession();
14068
14165
  this.adapter.updateRuntimeMeta({ providerSessionId: nextSessionId });
14069
14166
  this.onProviderSessionResolved?.({
14070
14167
  instanceId: this.instanceId,
@@ -14076,6 +14173,61 @@ ${effect.notification.body || ""}`.trim();
14076
14173
  });
14077
14174
  LOG.info("CLI", `[${this.type}] discovered provider session id: ${nextSessionId}`);
14078
14175
  }
14176
+ syncCanonicalHermesSavedHistoryIfNeeded() {
14177
+ if (this.type !== "hermes-cli" || !this.providerSessionId) return false;
14178
+ try {
14179
+ const canonicalPath = path11.join(os13.homedir(), ".hermes", "sessions", `session_${this.providerSessionId}.json`);
14180
+ if (!fs5.existsSync(canonicalPath)) return false;
14181
+ const stat4 = fs5.statSync(canonicalPath);
14182
+ if (stat4.mtimeMs <= this.lastCanonicalHermesSyncMtimeMs) return true;
14183
+ const rebuilt = rebuildHermesSavedHistoryFromCanonicalSession(this.providerSessionId);
14184
+ if (!rebuilt) return false;
14185
+ this.lastCanonicalHermesSyncMtimeMs = stat4.mtimeMs;
14186
+ const restoredHistory = readChatHistory(this.type, 0, 200, this.providerSessionId);
14187
+ this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
14188
+ role: message.role,
14189
+ content: message.content,
14190
+ kind: message.kind,
14191
+ senderName: message.senderName,
14192
+ receivedAt: message.receivedAt
14193
+ }));
14194
+ return true;
14195
+ } catch {
14196
+ return false;
14197
+ }
14198
+ }
14199
+ restorePersistedHistoryFromCurrentSession() {
14200
+ if (!this.providerSessionId) return;
14201
+ this.syncCanonicalHermesSavedHistoryIfNeeded();
14202
+ this.historyWriter.compactHistorySession(this.type, this.providerSessionId);
14203
+ const restoredHistory = readChatHistory(this.type, 0, 200, this.providerSessionId);
14204
+ this.historyWriter.seedSessionHistory(
14205
+ this.type,
14206
+ restoredHistory.messages,
14207
+ this.providerSessionId,
14208
+ this.instanceId
14209
+ );
14210
+ this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
14211
+ role: message.role,
14212
+ content: message.content,
14213
+ kind: message.kind,
14214
+ senderName: message.senderName,
14215
+ receivedAt: message.receivedAt
14216
+ }));
14217
+ this.suppressIdleHistoryReplay = restoredHistory.messages.length > 0;
14218
+ if (restoredHistory.messages.length > 0) {
14219
+ this.adapter.seedCommittedMessages(
14220
+ restoredHistory.messages.map((message) => ({
14221
+ role: message.role,
14222
+ content: message.content,
14223
+ timestamp: message.receivedAt,
14224
+ receivedAt: message.receivedAt,
14225
+ kind: message.kind,
14226
+ senderName: message.senderName
14227
+ }))
14228
+ );
14229
+ }
14230
+ }
14079
14231
  getProbeDirectories() {
14080
14232
  const dirs = /* @__PURE__ */ new Set();
14081
14233
  const addDir = (value) => {
@@ -54945,7 +55097,7 @@ var init_adhdev_daemon = __esm({
54945
55097
  init_version();
54946
55098
  init_src();
54947
55099
  init_runtime_defaults();
54948
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.94" });
55100
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.95" });
54949
55101
  AdhdevDaemon = class _AdhdevDaemon {
54950
55102
  localHttpServer = null;
54951
55103
  localWss = null;