@adhdev/daemon-core 0.9.76-rc.16 → 0.9.76-rc.18

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.
@@ -8,6 +8,7 @@ import { type ProviderModule } from './contracts.js';
8
8
  import type { ProviderInstance, ProviderState, InstanceContext, HotChatSessionState, SessionModalState } from './provider-instance.js';
9
9
  import { ProviderCliAdapter } from '../cli-adapters/provider-cli-adapter.js';
10
10
  import type { PtyTransportFactory } from '../cli-adapters/pty-transport.js';
11
+ import type { ChatMessage } from '../types.js';
11
12
  type PersistableCliHistoryMessage = {
12
13
  role: string;
13
14
  content: string;
@@ -113,6 +114,7 @@ export declare class CliProviderInstance implements ProviderInstance {
113
114
  private maybeAppendRuntimeRecoveryMessage;
114
115
  private appendRuntimeSystemMessage;
115
116
  private appendRuntimeMessage;
117
+ mergeRuntimeChatMessages(parsedMessages: ChatMessage[]): ChatMessage[];
116
118
  private mergeConversationMessages;
117
119
  private formatApprovalRequestMessage;
118
120
  private promoteProviderSessionId;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.9.76-rc.16",
3
+ "version": "0.9.76-rc.18",
4
4
  "description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -28,6 +28,10 @@ interface ApprovalSelectableInstance extends ProviderInstance {
28
28
  recordApprovalSelection?(buttonText: string): void;
29
29
  }
30
30
 
31
+ interface RuntimeChatMessageMerger extends ProviderInstance {
32
+ mergeRuntimeChatMessages?(messages: ChatMessage[]): ChatMessage[];
33
+ }
34
+
31
35
  type LegacyStringScript = (params?: Record<string, unknown> | string) => string;
32
36
 
33
37
  function getCurrentProviderType(h: CommandHelpers, fallback = ''): string {
@@ -250,6 +254,40 @@ function normalizeReadChatCommandStatus(status: unknown, activeModal: unknown):
250
254
  }
251
255
  }
252
256
 
257
+ function isGeneratingLikeStatus(status: unknown): boolean {
258
+ return status === 'generating' || status === 'streaming' || status === 'long_generating' || status === 'starting';
259
+ }
260
+
261
+ function shouldTrustCliAdapterTerminalStatus(parsedStatus: unknown, activeModal: unknown, adapter: CliAdapter, adapterStatus: any): boolean {
262
+ if (!isGeneratingLikeStatus(parsedStatus)) return false;
263
+ if (hasNonEmptyModalButtons(activeModal)) return false;
264
+ const adapterRawStatus = typeof adapterStatus?.status === 'string' ? adapterStatus.status.trim() : '';
265
+ if (adapterRawStatus !== 'idle') return false;
266
+ if (typeof adapter.isProcessing === 'function' && adapter.isProcessing()) return false;
267
+ return true;
268
+ }
269
+
270
+ function normalizeCliReadChatStatus(parsedStatus: unknown, activeModal: unknown, adapter: CliAdapter, adapterStatus: any): string {
271
+ if (shouldTrustCliAdapterTerminalStatus(parsedStatus, activeModal, adapter, adapterStatus)) return 'idle';
272
+ return typeof parsedStatus === 'string' && parsedStatus.trim() ? parsedStatus : 'idle';
273
+ }
274
+
275
+ function finalizeStreamingMessagesWhenIdle(messages: ChatMessage[], status: string): ChatMessage[] {
276
+ if (status !== 'idle') return messages;
277
+ return messages.map((message) => {
278
+ const meta = message.meta && typeof message.meta === 'object'
279
+ ? message.meta as Record<string, unknown>
280
+ : undefined;
281
+ const hasStreamingMeta = meta?.streaming === true;
282
+ if (message.bubbleState !== 'streaming' && !hasStreamingMeta) return message;
283
+ return {
284
+ ...message,
285
+ ...(message.bubbleState === 'streaming' ? { bubbleState: 'final' as const } : {}),
286
+ ...(hasStreamingMeta ? { meta: { ...meta, streaming: false } } : {}),
287
+ };
288
+ });
289
+ }
290
+
253
291
  function buildReadChatCommandResult(payload: Record<string, any>, args: any): CommandResult {
254
292
  let validatedPayload: Record<string, any>;
255
293
  const debugReadChat = payload?.debugReadChat && typeof payload.debugReadChat === 'object'
@@ -760,10 +798,17 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
760
798
  ? parsedRecord.coverage
761
799
  : undefined;
762
800
  const activeModal = parsedRecord.activeModal ?? parsedRecord.modal ?? null;
763
- const returnedStatus = parsedRecord.status || 'idle';
764
- LOG.debug('Command', `[read_chat] cli-like parsed provider=${adapter.cliType} target=${String(args?.targetSessionId || '')} adapterStatus=${String(adapterStatus.status || '')} parsedStatus=${String(parsedRecord.status || '')} parsedMsgCount=${parsedRecord.messages.length}`);
801
+ const returnedStatus = normalizeCliReadChatStatus(parsedRecord.status, activeModal, adapter, adapterStatus);
802
+ const runtimeMessageMerger = getTargetInstance(h, args) as RuntimeChatMessageMerger | null;
803
+ const parsedMessages = finalizeStreamingMessagesWhenIdle(parsedRecord.messages as ChatMessage[], returnedStatus);
804
+ const returnedMessages = runtimeMessageMerger?.category === 'cli'
805
+ && runtimeMessageMerger.type === adapter.cliType
806
+ && typeof runtimeMessageMerger.mergeRuntimeChatMessages === 'function'
807
+ ? runtimeMessageMerger.mergeRuntimeChatMessages(parsedMessages)
808
+ : parsedMessages;
809
+ LOG.debug('Command', `[read_chat] cli-like parsed provider=${adapter.cliType} target=${String(args?.targetSessionId || '')} adapterStatus=${String(adapterStatus.status || '')} parsedStatus=${String(parsedRecord.status || '')} parsedMsgCount=${parsedRecord.messages.length} returnedMsgCount=${returnedMessages.length}`);
765
810
  return buildReadChatCommandResult({
766
- messages: parsedRecord.messages,
811
+ messages: returnedMessages,
767
812
  status: returnedStatus,
768
813
  activeModal,
769
814
  debugReadChat: {
@@ -774,7 +819,7 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
774
819
  returnedStatus: String(returnedStatus || ''),
775
820
  shouldPreferAdapterMessages: false,
776
821
  parsedMsgCount: parsedRecord.messages.length,
777
- returnedMsgCount: parsedRecord.messages.length,
822
+ returnedMsgCount: returnedMessages.length,
778
823
  },
779
824
  ...(title ? { title } : {}),
780
825
  ...(providerSessionId ? { providerSessionId } : {}),
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import type { ProviderModule } from './contracts.js';
8
8
  import type { ProviderInstance, ProviderState, InstanceContext } from './provider-instance.js';
9
+ import type { ChatMessage } from '../types.js';
9
10
  import { ProviderCliAdapter } from '../cli-adapters/provider-cli-adapter.js';
10
11
  import type { PtyTransportFactory } from '../cli-adapters/pty-transport.js';
11
12
  export declare class CliProviderInstance implements ProviderInstance {
@@ -77,6 +78,7 @@ export declare class CliProviderInstance implements ProviderInstance {
77
78
  private formatMarkerTimestamp;
78
79
  private maybeAppendRuntimeRecoveryMessage;
79
80
  private appendRuntimeSystemMessage;
81
+ mergeRuntimeChatMessages(parsedMessages: ChatMessage[]): ChatMessage[];
80
82
  private mergeConversationMessages;
81
83
  private formatApprovalRequestMessage;
82
84
  private promoteProviderSessionId;
@@ -978,6 +978,10 @@ export class CliProviderInstance implements ProviderInstance {
978
978
  }
979
979
  }
980
980
 
981
+ mergeRuntimeChatMessages(parsedMessages: ChatMessage[]): ChatMessage[] {
982
+ return this.mergeConversationMessages(parsedMessages);
983
+ }
984
+
981
985
  private mergeConversationMessages(parsedMessages: any[]): ChatMessage[] {
982
986
  if (this.runtimeMessages.length === 0) return normalizeChatMessages(parsedMessages);
983
987