adhdev 0.9.36 → 0.9.37

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
@@ -12376,27 +12376,86 @@ function sliceFromOffset(text, start) {
12376
12376
  function hydrateCliParsedMessages(parsedMessages, options) {
12377
12377
  const { committedMessages, scope, lastOutputAt } = options;
12378
12378
  const referenceMessages = [...committedMessages];
12379
- const referenceComparables = referenceMessages.map((message) => normalizeComparableMessageContent(message?.content || ""));
12379
+ const referenceComparables = new Array(referenceMessages.length);
12380
12380
  const usedReferenceIndexes = /* @__PURE__ */ new Set();
12381
12381
  const now = options.now ?? Date.now();
12382
- const findReferenceTimestamp = (role, content, parsedIndex) => {
12382
+ let exactReferenceIndexesByKey = null;
12383
+ const exactReferenceCursorByKey = /* @__PURE__ */ new Map();
12384
+ const hasFiniteTimestamp = (message) => typeof message?.timestamp === "number" && Number.isFinite(message.timestamp);
12385
+ const getReferenceComparable = (index) => {
12386
+ if (typeof referenceComparables[index] === "string") return referenceComparables[index] || "";
12387
+ const comparable = normalizeComparableMessageContent(referenceMessages[index]?.content || "");
12388
+ referenceComparables[index] = comparable;
12389
+ return comparable;
12390
+ };
12391
+ const messagesShareStableIdentity = (parsed, reference) => {
12392
+ if (!parsed || !reference) return false;
12393
+ const parsedId = typeof parsed.id === "string" ? parsed.id.trim() : "";
12394
+ const referenceId = typeof reference.id === "string" ? reference.id.trim() : "";
12395
+ if (parsedId && referenceId && parsedId === referenceId) return true;
12396
+ return typeof parsed.index === "number" && Number.isFinite(parsed.index) && typeof reference.index === "number" && Number.isFinite(reference.index) && parsed.index === reference.index;
12397
+ };
12398
+ const exactReferenceKey = (role, comparable) => `${role}\0${comparable}`;
12399
+ const ensureExactReferenceIndex = () => {
12400
+ if (exactReferenceIndexesByKey) return exactReferenceIndexesByKey;
12401
+ const byKey = /* @__PURE__ */ new Map();
12402
+ for (let i = 0; i < referenceMessages.length; i++) {
12403
+ const candidate = referenceMessages[i];
12404
+ if (!candidate || candidate.role !== "user" && candidate.role !== "assistant" || !hasFiniteTimestamp(candidate)) continue;
12405
+ const comparable = getReferenceComparable(i);
12406
+ if (!comparable) continue;
12407
+ const key = exactReferenceKey(candidate.role, comparable);
12408
+ const indexes = byKey.get(key);
12409
+ if (indexes) {
12410
+ indexes.push(i);
12411
+ } else {
12412
+ byKey.set(key, [i]);
12413
+ }
12414
+ }
12415
+ exactReferenceIndexesByKey = byKey;
12416
+ return byKey;
12417
+ };
12418
+ const takeExactReferenceTimestamp = (role, normalizedContent) => {
12419
+ const key = exactReferenceKey(role, normalizedContent);
12420
+ const indexes = ensureExactReferenceIndex().get(key);
12421
+ if (!indexes) return void 0;
12422
+ let cursor = exactReferenceCursorByKey.get(key) || 0;
12423
+ while (cursor < indexes.length) {
12424
+ const candidateIndex = indexes[cursor];
12425
+ cursor += 1;
12426
+ if (usedReferenceIndexes.has(candidateIndex)) continue;
12427
+ const candidate = referenceMessages[candidateIndex];
12428
+ if (!candidate || candidate.role !== role || !hasFiniteTimestamp(candidate)) continue;
12429
+ usedReferenceIndexes.add(candidateIndex);
12430
+ exactReferenceCursorByKey.set(key, cursor);
12431
+ return candidate.timestamp;
12432
+ }
12433
+ exactReferenceCursorByKey.set(key, cursor);
12434
+ return void 0;
12435
+ };
12436
+ const findReferenceTimestamp = (message, role, content, parsedIndex) => {
12437
+ const sameIndex = referenceMessages[parsedIndex];
12438
+ if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && hasFiniteTimestamp(sameIndex) && messagesShareStableIdentity(message, sameIndex)) {
12439
+ usedReferenceIndexes.add(parsedIndex);
12440
+ return sameIndex.timestamp;
12441
+ }
12383
12442
  const normalizedContent = normalizeComparableMessageContent(content);
12384
12443
  if (!normalizedContent) return void 0;
12385
- const sameIndex = referenceMessages[parsedIndex];
12386
- if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && referenceComparables[parsedIndex] === normalizedContent && typeof sameIndex.timestamp === "number" && Number.isFinite(sameIndex.timestamp)) {
12444
+ if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && getReferenceComparable(parsedIndex) === normalizedContent && hasFiniteTimestamp(sameIndex)) {
12387
12445
  usedReferenceIndexes.add(parsedIndex);
12388
12446
  return sameIndex.timestamp;
12389
12447
  }
12448
+ const exactTimestamp = takeExactReferenceTimestamp(role, normalizedContent);
12449
+ if (typeof exactTimestamp === "number") return exactTimestamp;
12390
12450
  for (let i = 0; i < referenceMessages.length; i++) {
12391
12451
  if (usedReferenceIndexes.has(i)) continue;
12392
12452
  const candidate = referenceMessages[i];
12393
12453
  if (!candidate || candidate.role !== role) continue;
12394
- const candidateContent = referenceComparables[i];
12454
+ const candidateContent = getReferenceComparable(i);
12395
12455
  if (!candidateContent) continue;
12396
- const exactMatch = candidateContent === normalizedContent;
12397
12456
  const fuzzyMatch = candidateContent.includes(normalizedContent) || normalizedContent.includes(candidateContent);
12398
- if (!exactMatch && !fuzzyMatch) continue;
12399
- if (typeof candidate.timestamp === "number" && Number.isFinite(candidate.timestamp)) {
12457
+ if (!fuzzyMatch) continue;
12458
+ if (hasFiniteTimestamp(candidate)) {
12400
12459
  usedReferenceIndexes.add(i);
12401
12460
  return candidate.timestamp;
12402
12461
  }
@@ -12407,7 +12466,7 @@ function hydrateCliParsedMessages(parsedMessages, options) {
12407
12466
  const role = message.role;
12408
12467
  const content = typeof message.content === "string" ? message.content : String(message.content || "");
12409
12468
  const parsedTimestamp = typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : void 0;
12410
- const referenceTimestamp = parsedTimestamp ?? findReferenceTimestamp(role, content, index);
12469
+ const referenceTimestamp = parsedTimestamp ?? findReferenceTimestamp(message, role, content, index);
12411
12470
  const fallbackTimestamp = role === "user" ? scope?.startedAt || now : lastOutputAt || scope?.startedAt || now;
12412
12471
  const timestamp = referenceTimestamp ?? fallbackTimestamp;
12413
12472
  return {
@@ -14027,11 +14086,12 @@ var init_provider_cli_adapter = __esm({
14027
14086
  };
14028
14087
  }
14029
14088
  // ─── Public API (CliAdapter) ───────────────────
14030
- getStatus() {
14031
- const startupModal = this.startupParseGate ? this.runParseApproval(this.recentOutputBuffer) : null;
14089
+ getStatus(options = {}) {
14090
+ const allowParse = options.allowParse !== false;
14091
+ const startupModal = allowParse && this.startupParseGate ? this.runParseApproval(this.recentOutputBuffer) : null;
14032
14092
  let effectiveStatus = this.projectEffectiveStatus(startupModal);
14033
14093
  let effectiveModal = startupModal || this.activeModal;
14034
- if (!startupModal && !effectiveModal && typeof this.cliScripts?.parseOutput === "function") {
14094
+ if (allowParse && !startupModal && !effectiveModal && typeof this.cliScripts?.parseOutput === "function") {
14035
14095
  let parsed = this.getFreshParsedStatusCache();
14036
14096
  if (!parsed && effectiveStatus !== "idle") {
14037
14097
  const now = Date.now();
@@ -15332,7 +15392,7 @@ var init_cli_provider_instance = __esm({
15332
15392
  return this.presentationMode;
15333
15393
  }
15334
15394
  getHotChatSessionState() {
15335
- const adapterStatus = this.adapter.getStatus();
15395
+ const adapterStatus = this.adapter.getStatus({ allowParse: false });
15336
15396
  const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
15337
15397
  const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
15338
15398
  const runtime = this.adapter.getRuntimeMetadata();
@@ -88235,7 +88295,7 @@ var init_adhdev_daemon = __esm({
88235
88295
  init_version();
88236
88296
  init_src();
88237
88297
  init_runtime_defaults();
88238
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.36" });
88298
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.37" });
88239
88299
  AdhdevDaemon = class _AdhdevDaemon {
88240
88300
  localHttpServer = null;
88241
88301
  localWss = null;
@@ -88252,7 +88312,7 @@ var init_adhdev_daemon = __esm({
88252
88312
  p2pChatOutputActiveAt = /* @__PURE__ */ new Map();
88253
88313
  p2pChatOutputFlushTimer = null;
88254
88314
  hotChatSnapshotCache = null;
88255
- static HOT_CHAT_SNAPSHOT_CACHE_TTL_MS = 1500;
88315
+ static HOT_CHAT_SNAPSHOT_CACHE_TTL_MS = 2400;
88256
88316
  static CHAT_OUTPUT_ACTIVITY_HOT_MS = DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS;
88257
88317
  static CHAT_OUTPUT_FLUSH_DEBOUNCE_MS = 700;
88258
88318
  components = null;