adhdev 0.8.98 → 0.8.99

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
@@ -1259,6 +1259,9 @@ function normalizeProviderSessionId(providerType, providerSessionId) {
1259
1259
  if (normalizedProviderType === "hermes-cli" && !HERMES_SESSION_ID_RE.test(normalizedId)) {
1260
1260
  return "";
1261
1261
  }
1262
+ if (normalizedProviderType === "claude-cli" && !CLAUDE_SESSION_ID_RE.test(normalizedId)) {
1263
+ return "";
1264
+ }
1262
1265
  return normalizedId;
1263
1266
  }
1264
1267
  function isLegacyVolatileSessionReadKey(key) {
@@ -1266,11 +1269,12 @@ function isLegacyVolatileSessionReadKey(key) {
1266
1269
  if (!normalizedKey) return false;
1267
1270
  return normalizedKey.startsWith("provider:codex:vscode-webview://");
1268
1271
  }
1269
- var HERMES_SESSION_ID_RE;
1272
+ var HERMES_SESSION_ID_RE, CLAUDE_SESSION_ID_RE;
1270
1273
  var init_provider_session_id = __esm({
1271
1274
  "../../oss/packages/daemon-core/src/providers/provider-session-id.ts"() {
1272
1275
  "use strict";
1273
1276
  HERMES_SESSION_ID_RE = /^\d{8}_\d{6}_[a-z0-9]+$/i;
1277
+ CLAUDE_SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
1274
1278
  }
1275
1279
  });
1276
1280
 
@@ -4677,9 +4681,16 @@ function extractCanonicalHermesMessageTimestamp(message, fallbackTs) {
4677
4681
  if (Number.isFinite(stringTimestamp) && stringTimestamp > 0) return stringTimestamp;
4678
4682
  return fallbackTs;
4679
4683
  }
4680
- function readExistingHermesSessionStartRecord(historySessionId) {
4684
+ function extractTimestampValue(value) {
4685
+ const numericTimestamp = Number(value || 0);
4686
+ if (Number.isFinite(numericTimestamp) && numericTimestamp > 0) return numericTimestamp;
4687
+ const stringTimestamp = typeof value === "string" ? Date.parse(value) : NaN;
4688
+ if (Number.isFinite(stringTimestamp) && stringTimestamp > 0) return stringTimestamp;
4689
+ return 0;
4690
+ }
4691
+ function readExistingSessionStartRecord(agentType, historySessionId) {
4681
4692
  try {
4682
- const dir = path7.join(HISTORY_DIR, "hermes-cli");
4693
+ const dir = path7.join(HISTORY_DIR, agentType);
4683
4694
  if (!fs3.existsSync(dir)) return null;
4684
4695
  const files = listHistoryFiles(dir, historySessionId).sort();
4685
4696
  for (const file2 of files) {
@@ -4700,6 +4711,28 @@ function readExistingHermesSessionStartRecord(historySessionId) {
4700
4711
  return null;
4701
4712
  }
4702
4713
  }
4714
+ function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
4715
+ if (records.length === 0) return false;
4716
+ try {
4717
+ const dir = path7.join(HISTORY_DIR, agentType);
4718
+ fs3.mkdirSync(dir, { recursive: true });
4719
+ const prefix = `${historySessionId.replace(/[^a-zA-Z0-9_-]/g, "_")}_`;
4720
+ for (const file2 of fs3.readdirSync(dir)) {
4721
+ if (file2.startsWith(prefix) && file2.endsWith(".jsonl")) {
4722
+ fs3.unlinkSync(path7.join(dir, file2));
4723
+ }
4724
+ }
4725
+ const targetDate = new Date(records[records.length - 1].receivedAt || Date.now()).toISOString().slice(0, 10);
4726
+ const filePath = path7.join(dir, `${prefix}${targetDate}.jsonl`);
4727
+ fs3.writeFileSync(filePath, `${records.map((record2) => JSON.stringify(record2)).join("\n")}
4728
+ `, "utf-8");
4729
+ invalidatePersistedSavedHistoryIndex(agentType, dir);
4730
+ savedHistorySessionCache.delete(agentType.replace(/[^a-zA-Z0-9_-]/g, "_"));
4731
+ return true;
4732
+ } catch {
4733
+ return false;
4734
+ }
4735
+ }
4703
4736
  function rebuildHermesSavedHistoryFromCanonicalSession(historySessionId) {
4704
4737
  const normalizedSessionId = normalizeSavedHistorySessionId("hermes-cli", historySessionId);
4705
4738
  if (!normalizedSessionId) return false;
@@ -4710,7 +4743,7 @@ function rebuildHermesSavedHistoryFromCanonicalSession(historySessionId) {
4710
4743
  const canonicalMessages = Array.isArray(raw.messages) ? raw.messages : [];
4711
4744
  const dir = path7.join(HISTORY_DIR, "hermes-cli");
4712
4745
  fs3.mkdirSync(dir, { recursive: true });
4713
- const existingSessionStart = readExistingHermesSessionStartRecord(normalizedSessionId);
4746
+ const existingSessionStart = readExistingSessionStartRecord("hermes-cli", normalizedSessionId);
4714
4747
  const records = [];
4715
4748
  if (existingSessionStart) {
4716
4749
  records.push({
@@ -4762,20 +4795,167 @@ function rebuildHermesSavedHistoryFromCanonicalSession(historySessionId) {
4762
4795
  });
4763
4796
  }
4764
4797
  }
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));
4798
+ return rewriteCanonicalSavedHistory("hermes-cli", normalizedSessionId, records);
4799
+ } catch {
4800
+ return false;
4801
+ }
4802
+ }
4803
+ function resolveClaudeProjectTranscriptPath(historySessionId, workspace) {
4804
+ const claudeProjectsDir = path7.join(os6.homedir(), ".claude", "projects");
4805
+ if (!fs3.existsSync(claudeProjectsDir)) return null;
4806
+ const normalizedWorkspace = typeof workspace === "string" ? workspace.trim() : "";
4807
+ if (normalizedWorkspace) {
4808
+ const directPath = path7.join(claudeProjectsDir, normalizedWorkspace.replace(/[\\/]/g, "-"), `${historySessionId}.jsonl`);
4809
+ if (fs3.existsSync(directPath)) return directPath;
4810
+ }
4811
+ const stack = [claudeProjectsDir];
4812
+ while (stack.length > 0) {
4813
+ const current = stack.pop();
4814
+ if (!current) continue;
4815
+ for (const entry of fs3.readdirSync(current, { withFileTypes: true })) {
4816
+ const entryPath = path7.join(current, entry.name);
4817
+ if (entry.isDirectory()) {
4818
+ stack.push(entryPath);
4819
+ continue;
4820
+ }
4821
+ if (entry.isFile() && entry.name === `${historySessionId}.jsonl`) {
4822
+ return entryPath;
4770
4823
  }
4771
4824
  }
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;
4825
+ }
4826
+ return null;
4827
+ }
4828
+ function extractClaudeAssistantContentParts(content) {
4829
+ if (typeof content === "string") {
4830
+ const trimmed = content.trim();
4831
+ return trimmed ? [{ content: trimmed, kind: "standard", role: "assistant" }] : [];
4832
+ }
4833
+ if (!Array.isArray(content)) return [];
4834
+ const parts = [];
4835
+ for (const block of content) {
4836
+ if (!block || typeof block !== "object") continue;
4837
+ const record2 = block;
4838
+ const type = String(record2.type || "").trim();
4839
+ if (type === "text") {
4840
+ const text = String(record2.text || "").trim();
4841
+ if (text) parts.push({ content: text, kind: "standard", role: "assistant" });
4842
+ continue;
4843
+ }
4844
+ if (type === "tool_use") {
4845
+ const name = String(record2.name || "").trim() || "Tool";
4846
+ const input = record2.input && typeof record2.input === "object" ? record2.input : null;
4847
+ const command = input ? String(input.command || "").trim() : "";
4848
+ const summary = command ? `${name}: ${command}` : name;
4849
+ if (summary) parts.push({ content: summary, kind: "tool", senderName: "Tool", role: "assistant" });
4850
+ }
4851
+ }
4852
+ return parts;
4853
+ }
4854
+ function extractClaudeUserContentParts(content) {
4855
+ if (typeof content === "string") {
4856
+ const trimmed = content.trim();
4857
+ return trimmed ? [{ role: "user", content: trimmed, kind: "standard" }] : [];
4858
+ }
4859
+ if (!Array.isArray(content)) return [];
4860
+ const parts = [];
4861
+ for (const block of content) {
4862
+ if (!block || typeof block !== "object") continue;
4863
+ const record2 = block;
4864
+ const type = String(record2.type || "").trim();
4865
+ if (type === "text") {
4866
+ const text = String(record2.text || "").trim();
4867
+ if (text) parts.push({ role: "user", content: text, kind: "standard" });
4868
+ continue;
4869
+ }
4870
+ if (type === "tool_result") {
4871
+ const rawContent = record2.content;
4872
+ const text = typeof rawContent === "string" ? rawContent.trim() : Array.isArray(rawContent) ? rawContent.map((entry) => {
4873
+ if (typeof entry === "string") return entry.trim();
4874
+ if (!entry || typeof entry !== "object") return "";
4875
+ const nested = entry;
4876
+ if (typeof nested.text === "string") return nested.text.trim();
4877
+ if (typeof nested.content === "string") return nested.content.trim();
4878
+ return "";
4879
+ }).filter(Boolean).join("\n") : "";
4880
+ if (text) parts.push({ role: "assistant", content: text, kind: "tool", senderName: "Tool" });
4881
+ }
4882
+ }
4883
+ return parts;
4884
+ }
4885
+ function rebuildClaudeSavedHistoryFromNativeProject(historySessionId, workspace) {
4886
+ const normalizedSessionId = normalizeSavedHistorySessionId("claude-cli", historySessionId);
4887
+ if (!normalizedSessionId) return false;
4888
+ try {
4889
+ const transcriptPath = resolveClaudeProjectTranscriptPath(normalizedSessionId, workspace);
4890
+ if (!transcriptPath) return false;
4891
+ const lines = fs3.readFileSync(transcriptPath, "utf-8").split("\n").filter(Boolean);
4892
+ const records = [];
4893
+ const existingSessionStart = readExistingSessionStartRecord("claude-cli", normalizedSessionId);
4894
+ if (existingSessionStart) {
4895
+ records.push({
4896
+ ...existingSessionStart,
4897
+ historySessionId: normalizedSessionId
4898
+ });
4899
+ }
4900
+ let fallbackTs = Date.now();
4901
+ for (const line of lines) {
4902
+ let parsed = null;
4903
+ try {
4904
+ parsed = JSON.parse(line);
4905
+ } catch {
4906
+ parsed = null;
4907
+ }
4908
+ if (!parsed) continue;
4909
+ const parsedSessionId = String(parsed.sessionId || "").trim();
4910
+ if (parsedSessionId && parsedSessionId !== normalizedSessionId) continue;
4911
+ const receivedAt = extractTimestampValue(parsed.timestamp) || fallbackTs;
4912
+ fallbackTs = receivedAt + 1;
4913
+ const parsedWorkspace = String(parsed.cwd || workspace || "").trim();
4914
+ if (records.length === 0 && parsedWorkspace) {
4915
+ records.push({
4916
+ ts: new Date(receivedAt).toISOString(),
4917
+ receivedAt,
4918
+ role: "system",
4919
+ kind: "session_start",
4920
+ content: parsedWorkspace,
4921
+ agent: "claude-cli",
4922
+ historySessionId: normalizedSessionId,
4923
+ workspace: parsedWorkspace
4924
+ });
4925
+ }
4926
+ const type = String(parsed.type || "").trim();
4927
+ const message = parsed.message && typeof parsed.message === "object" ? parsed.message : null;
4928
+ if (type === "user" && message) {
4929
+ for (const part of extractClaudeUserContentParts(message.content)) {
4930
+ records.push({
4931
+ ts: new Date(receivedAt).toISOString(),
4932
+ receivedAt,
4933
+ role: part.role,
4934
+ content: part.content,
4935
+ kind: part.kind,
4936
+ senderName: part.senderName,
4937
+ agent: "claude-cli",
4938
+ historySessionId: normalizedSessionId
4939
+ });
4940
+ }
4941
+ continue;
4942
+ }
4943
+ if (type === "assistant" && message) {
4944
+ for (const part of extractClaudeAssistantContentParts(message.content)) {
4945
+ records.push({
4946
+ ts: new Date(receivedAt).toISOString(),
4947
+ receivedAt,
4948
+ role: "assistant",
4949
+ content: part.content,
4950
+ kind: part.kind,
4951
+ senderName: part.senderName,
4952
+ agent: "claude-cli",
4953
+ historySessionId: normalizedSessionId
4954
+ });
4955
+ }
4956
+ }
4957
+ }
4958
+ return rewriteCanonicalSavedHistory("claude-cli", normalizedSessionId, records);
4779
4959
  } catch {
4780
4960
  return false;
4781
4961
  }
@@ -14657,7 +14837,7 @@ var init_cli_provider_instance = __esm({
14657
14837
  parsedMessages = historyMessageCount > 0 ? parsedMessages.slice(-historyMessageCount) : [];
14658
14838
  }
14659
14839
  const mergedMessages = this.mergeConversationMessages(parsedMessages);
14660
- const canonicalHermesBackedHistory = this.syncCanonicalHermesSavedHistoryIfNeeded();
14840
+ const canonicalBackedHistory = this.syncCanonicalSavedHistoryIfNeeded();
14661
14841
  const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
14662
14842
  if (parsedMessages.length > 0) {
14663
14843
  const shouldSkipReplayPersist = this.suppressIdleHistoryReplay && adapterStatus.status === "idle" && parsedStatus?.status === "idle";
@@ -14675,7 +14855,7 @@ var init_cli_provider_instance = __esm({
14675
14855
  senderName: typeof message.senderName === "string" ? message.senderName : void 0,
14676
14856
  receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
14677
14857
  }));
14678
- if (!canonicalHermesBackedHistory && !shouldSkipReplayPersist && normalizedMessagesToSave.length > 0) {
14858
+ if (!canonicalBackedHistory && !shouldSkipReplayPersist && normalizedMessagesToSave.length > 0) {
14679
14859
  const incrementalMessages = buildIncrementalHistoryAppendMessages(this.lastPersistedHistoryMessages, normalizedMessagesToSave);
14680
14860
  this.historyWriter.appendNewMessages(
14681
14861
  this.type,
@@ -14685,7 +14865,7 @@ var init_cli_provider_instance = __esm({
14685
14865
  this.providerSessionId
14686
14866
  );
14687
14867
  }
14688
- if (!canonicalHermesBackedHistory) {
14868
+ if (!canonicalBackedHistory) {
14689
14869
  this.lastPersistedHistoryMessages = normalizedMessagesToSave;
14690
14870
  }
14691
14871
  }
@@ -15162,32 +15342,52 @@ ${effect.notification.body || ""}`.trim();
15162
15342
  });
15163
15343
  LOG.info("CLI", `[${this.type}] discovered provider session id: ${nextSessionId}`);
15164
15344
  }
15165
- syncCanonicalHermesSavedHistoryIfNeeded() {
15166
- if (this.type !== "hermes-cli" || !this.providerSessionId) return false;
15167
- try {
15168
- const canonicalPath = path12.join(os14.homedir(), ".hermes", "sessions", `session_${this.providerSessionId}.json`);
15169
- if (!fs5.existsSync(canonicalPath)) return false;
15170
- const stat4 = fs5.statSync(canonicalPath);
15171
- if (stat4.mtimeMs <= this.lastCanonicalHermesSyncMtimeMs) return true;
15172
- const rebuilt = rebuildHermesSavedHistoryFromCanonicalSession(this.providerSessionId);
15173
- if (!rebuilt) return false;
15174
- this.lastCanonicalHermesSyncMtimeMs = stat4.mtimeMs;
15175
- const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId);
15176
- this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
15177
- role: message.role,
15178
- content: message.content,
15179
- kind: message.kind,
15180
- senderName: message.senderName,
15181
- receivedAt: message.receivedAt
15182
- }));
15183
- return true;
15184
- } catch {
15185
- return false;
15345
+ syncCanonicalSavedHistoryIfNeeded() {
15346
+ if (!this.providerSessionId) return false;
15347
+ if (this.type === "hermes-cli") {
15348
+ try {
15349
+ const canonicalPath = path12.join(os14.homedir(), ".hermes", "sessions", `session_${this.providerSessionId}.json`);
15350
+ if (!fs5.existsSync(canonicalPath)) return false;
15351
+ const stat4 = fs5.statSync(canonicalPath);
15352
+ if (stat4.mtimeMs <= this.lastCanonicalHermesSyncMtimeMs) return true;
15353
+ const rebuilt = rebuildHermesSavedHistoryFromCanonicalSession(this.providerSessionId);
15354
+ if (!rebuilt) return false;
15355
+ this.lastCanonicalHermesSyncMtimeMs = stat4.mtimeMs;
15356
+ const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId);
15357
+ this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
15358
+ role: message.role,
15359
+ content: message.content,
15360
+ kind: message.kind,
15361
+ senderName: message.senderName,
15362
+ receivedAt: message.receivedAt
15363
+ }));
15364
+ return true;
15365
+ } catch {
15366
+ return false;
15367
+ }
15186
15368
  }
15369
+ if (this.type === "claude-cli") {
15370
+ try {
15371
+ const rebuilt = rebuildClaudeSavedHistoryFromNativeProject(this.providerSessionId, this.workingDir);
15372
+ if (!rebuilt) return false;
15373
+ const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId);
15374
+ this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
15375
+ role: message.role,
15376
+ content: message.content,
15377
+ kind: message.kind,
15378
+ senderName: message.senderName,
15379
+ receivedAt: message.receivedAt
15380
+ }));
15381
+ return true;
15382
+ } catch {
15383
+ return false;
15384
+ }
15385
+ }
15386
+ return false;
15187
15387
  }
15188
15388
  restorePersistedHistoryFromCurrentSession() {
15189
15389
  if (!this.providerSessionId) return;
15190
- this.syncCanonicalHermesSavedHistoryIfNeeded();
15390
+ this.syncCanonicalSavedHistoryIfNeeded();
15191
15391
  this.historyWriter.compactHistorySession(this.type, this.providerSessionId);
15192
15392
  const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId);
15193
15393
  this.historyWriter.seedSessionHistory(
@@ -86850,7 +87050,7 @@ var init_adhdev_daemon = __esm({
86850
87050
  init_version();
86851
87051
  init_src();
86852
87052
  init_runtime_defaults();
86853
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.98" });
87053
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.99" });
86854
87054
  AdhdevDaemon = class _AdhdevDaemon {
86855
87055
  localHttpServer = null;
86856
87056
  localWss = null;