@adhdev/daemon-core 0.9.63 → 0.9.64

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/session-host-core",
3
- "version": "0.9.63",
3
+ "version": "0.9.64",
4
4
  "description": "ADHDev local session host core \u2014 session registry, protocol, buffers",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.9.63",
3
+ "version": "0.9.64",
4
4
  "description": "ADHDev daemon core \u2014 CDP, IDE detection, providers, command execution",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -344,6 +344,36 @@ function findLastMessageIndexBySignature(messages: ChatMessage[], signature: str
344
344
  return -1;
345
345
  }
346
346
 
347
+ function isReadChatConversationAnchorMessage(message: ChatMessage | null | undefined): boolean {
348
+ if (!message) return false;
349
+ const role = String(message.role || '').trim().toLowerCase();
350
+ if (role !== 'user' && role !== 'assistant') return false;
351
+ const kind = String(message.kind || 'standard').trim().toLowerCase();
352
+ return !kind || kind === 'standard';
353
+ }
354
+
355
+ function buildVisibleReadChatTailMessages(messages: ChatMessage[], tailLimit: number): ChatMessage[] {
356
+ const totalMessages = messages.length;
357
+ if (tailLimit <= 0 || totalMessages <= tailLimit) return messages;
358
+
359
+ const tailMessages = messages.slice(-tailLimit);
360
+ if (tailMessages.some(isReadChatConversationAnchorMessage)) return tailMessages;
361
+
362
+ const hiddenMessages = messages.slice(0, totalMessages - tailLimit);
363
+ const anchors: ChatMessage[] = [];
364
+ const seenRoles = new Set<string>();
365
+ for (let index = hiddenMessages.length - 1; index >= 0 && anchors.length < 2; index -= 1) {
366
+ const message = hiddenMessages[index];
367
+ if (!isReadChatConversationAnchorMessage(message)) continue;
368
+ const role = String(message.role || '').trim().toLowerCase();
369
+ if (seenRoles.has(role)) continue;
370
+ seenRoles.add(role);
371
+ anchors.unshift(message);
372
+ }
373
+
374
+ return anchors.length > 0 ? [...anchors, ...tailMessages] : tailMessages;
375
+ }
376
+
347
377
  function buildBoundedTailSync(messages: ChatMessage[], cursor: Required<ReadChatCursor>): {
348
378
  syncMode: ReadChatSyncMode;
349
379
  replaceFrom: number;
@@ -352,9 +382,7 @@ function buildBoundedTailSync(messages: ChatMessage[], cursor: Required<ReadChat
352
382
  lastMessageSignature: string;
353
383
  } {
354
384
  const totalMessages = messages.length;
355
- const tailMessages = cursor.tailLimit > 0 && totalMessages > cursor.tailLimit
356
- ? messages.slice(-cursor.tailLimit)
357
- : messages;
385
+ const tailMessages = buildVisibleReadChatTailMessages(messages, cursor.tailLimit);
358
386
  return {
359
387
  syncMode: 'full',
360
388
  replaceFrom: 0,
@@ -495,8 +523,8 @@ function buildReadChatCommandResult(payload: Record<string, any>, args: any): Co
495
523
  const messages = collapseReplayDuplicatesFromReadChat(normalizeReadChatMessages(validatedPayload));
496
524
  const cursor = normalizeReadChatCursor(args);
497
525
  if (!cursor.knownMessageCount && !cursor.lastMessageSignature && cursor.tailLimit > 0 && messages.length > cursor.tailLimit) {
498
- const tailMessages = messages.slice(-cursor.tailLimit);
499
- const lastMessageSignature = getChatMessageSignature(tailMessages[tailMessages.length - 1]);
526
+ const tailMessages = buildVisibleReadChatTailMessages(messages, cursor.tailLimit);
527
+ const lastMessageSignature = getChatMessageSignature(messages[messages.length - 1]);
500
528
  return {
501
529
  success: true,
502
530
  ...validatedPayload,