@adhdev/daemon-core 0.7.5 → 0.7.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.7.5",
3
+ "version": "0.7.6",
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",
@@ -24,6 +24,12 @@ export function forwardAgentStreamsToIdeInstance(
24
24
  activeModal: stream.activeModal || null,
25
25
  model: stream.model || undefined,
26
26
  mode: stream.mode || undefined,
27
+ sessionId: stream.sessionId || stream.instanceId || undefined,
28
+ title: stream.title || stream.agentName || undefined,
29
+ agentType: stream.agentType || undefined,
30
+ agentName: stream.agentName || undefined,
31
+ extensionId: stream.extensionId || undefined,
32
+ inputContent: stream.inputContent || '',
27
33
  });
28
34
  }
29
35
  }
@@ -32,6 +32,10 @@ export class ExtensionProviderInstance implements ProviderInstance {
32
32
  // meta
33
33
  private instanceId: string;
34
34
  private ideType: string = '';
35
+ private chatId: string | null = null;
36
+ private chatTitle: string | null = null;
37
+ private agentName: string = '';
38
+ private extensionId: string = '';
35
39
 
36
40
  constructor(provider: ProviderModule) {
37
41
  this.type = provider.type;
@@ -69,8 +73,8 @@ export class ExtensionProviderInstance implements ProviderInstance {
69
73
  category: 'extension',
70
74
  status: this.currentStatus as ProviderState['status'],
71
75
  activeChat: this.messages.length > 0 ? {
72
- id: `${this.type}_session`,
73
- title: this.provider.name,
76
+ id: this.chatId || this.instanceId,
77
+ title: this.chatTitle || this.agentName || this.provider.name,
74
78
  status: this.currentStatus,
75
79
  messages: this.messages,
76
80
  activeModal: this.activeModal,
@@ -94,6 +98,10 @@ export class ExtensionProviderInstance implements ProviderInstance {
94
98
  if (data?.activeModal !== undefined) this.activeModal = data.activeModal;
95
99
  if (data?.model) this.currentModel = data.model;
96
100
  if (data?.mode) this.currentMode = data.mode;
101
+ if (typeof data?.sessionId === 'string' && data.sessionId.trim()) this.chatId = data.sessionId;
102
+ if (typeof data?.title === 'string' && data.title.trim()) this.chatTitle = data.title;
103
+ if (typeof data?.agentName === 'string' && data.agentName.trim()) this.agentName = data.agentName;
104
+ if (typeof data?.extensionId === 'string' && data.extensionId.trim()) this.extensionId = data.extensionId;
97
105
  if (data?.status) {
98
106
  const newStatus = data.status;
99
107
  this.detectTransition(newStatus, data);
@@ -117,12 +125,6 @@ export class ExtensionProviderInstance implements ProviderInstance {
117
125
  }
118
126
 
119
127
  // ─── status transition detect ──────────────────────────────
120
- // NOTE: Extension transitions are TRACKED but NOT emitted as events.
121
- // The parent IdeProviderInstance already emits identical events
122
- // (generating_started, generating_completed, waiting_approval)
123
- // via its own detectAgentTransitions(). Emitting here would cause
124
- // duplicate toasts with slightly different content.
125
-
126
128
  private detectTransition(newStatus: string, data: any): void {
127
129
  const now = Date.now();
128
130
  const agentStatus = (newStatus === 'streaming' || newStatus === 'generating') ? 'generating'
@@ -136,13 +138,44 @@ export class ExtensionProviderInstance implements ProviderInstance {
136
138
  : undefined;
137
139
 
138
140
  if (agentStatus !== this.lastAgentStatus) {
139
- // Track generating start time (for monitor elapsed calculation)
140
141
  if (this.lastAgentStatus === 'idle' && agentStatus === 'generating') {
141
142
  this.generatingStartedAt = now;
143
+ this.pushEvent({
144
+ event: 'agent:generating_started',
145
+ chatTitle: this.resolveChatTitle(data),
146
+ timestamp: now,
147
+ ideType: this.ideType || this.type,
148
+ agentType: this.type,
149
+ agentName: this.agentName || this.provider.name,
150
+ extensionId: this.extensionId || this.type,
151
+ });
152
+ } else if (agentStatus === 'waiting_approval') {
153
+ if (!this.generatingStartedAt) this.generatingStartedAt = now;
154
+ this.pushEvent({
155
+ event: 'agent:waiting_approval',
156
+ chatTitle: this.resolveChatTitle(data),
157
+ timestamp: now,
158
+ ideType: this.ideType || this.type,
159
+ agentType: this.type,
160
+ agentName: this.agentName || this.provider.name,
161
+ extensionId: this.extensionId || this.type,
162
+ modalMessage: data?.activeModal?.message,
163
+ modalButtons: data?.activeModal?.buttons,
164
+ });
142
165
  } else if (agentStatus === 'idle' && (this.lastAgentStatus === 'generating' || this.lastAgentStatus === 'waiting_approval')) {
166
+ const duration = this.generatingStartedAt ? Math.round((now - this.generatingStartedAt) / 1000) : 0;
167
+ this.pushEvent({
168
+ event: 'agent:generating_completed',
169
+ chatTitle: this.resolveChatTitle(data),
170
+ duration,
171
+ timestamp: now,
172
+ ideType: this.ideType || this.type,
173
+ agentType: this.type,
174
+ agentName: this.agentName || this.provider.name,
175
+ extensionId: this.extensionId || this.type,
176
+ });
143
177
  this.generatingStartedAt = 0;
144
178
  }
145
- // Do NOT pushEvent for transitions — parent IDE instance handles these
146
179
  this.lastAgentStatus = agentStatus;
147
180
  }
148
181
 
@@ -164,4 +197,11 @@ export class ExtensionProviderInstance implements ProviderInstance {
164
197
  this.events = [];
165
198
  return events;
166
199
  }
200
+
201
+ private resolveChatTitle(data: any): string {
202
+ const title = typeof data?.title === 'string' && data.title.trim()
203
+ ? data.title.trim()
204
+ : this.chatTitle;
205
+ return title || this.agentName || this.provider.name;
206
+ }
167
207
  }
@@ -75,16 +75,13 @@ export class ProviderInstanceManager {
75
75
  try {
76
76
  const state = instance.getState();
77
77
  states.push(state);
78
-
79
- // pending events propagation
80
- for (const event of state.pendingEvents) {
81
- for (const listener of this.eventListeners) {
82
- listener({
83
- ...event,
84
- providerType: instance.type,
85
- instanceId: state.instanceId,
86
- targetSessionId: state.instanceId,
87
- providerCategory: state.category,
78
+ this.emitPendingEvents(instance.type, state);
79
+ if (state.category === 'ide') {
80
+ for (const childState of state.extensions) {
81
+ this.emitPendingEvents(childState.type, childState, {
82
+ targetSessionId: childState.instanceId,
83
+ workspaceName: state.workspace || undefined,
84
+ parentSessionId: state.instanceId,
88
85
  });
89
86
  }
90
87
  }
@@ -141,6 +138,26 @@ export class ProviderInstanceManager {
141
138
  this.eventListeners.push(listener);
142
139
  }
143
140
 
141
+ private emitPendingEvents(
142
+ providerType: string,
143
+ state: ProviderState,
144
+ extra: Record<string, unknown> = {},
145
+ ): void {
146
+ for (const event of state.pendingEvents) {
147
+ for (const listener of this.eventListeners) {
148
+ listener({
149
+ ...event,
150
+ providerType,
151
+ instanceId: state.instanceId,
152
+ targetSessionId: state.instanceId,
153
+ providerCategory: state.category,
154
+ workspaceName: state.workspace || undefined,
155
+ ...extra,
156
+ });
157
+ }
158
+ }
159
+ }
160
+
144
161
  /**
145
162
  * Forward event to specific Instance
146
163
  */