@adhdev/daemon-core 0.6.77 → 0.6.79

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.
@@ -71,8 +71,8 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
71
71
  // Alternative: AgentStreamManager (script fail when)
72
72
  if (h.agentStream) {
73
73
  const cdp = h.getCdp();
74
- if (cdp) {
75
- const streams = await h.agentStream.collectAgentStreams(cdp);
74
+ if (cdp && h.currentIdeType) {
75
+ const streams = await h.agentStream.collectAgentStreams(cdp, h.currentIdeType);
76
76
  const stream = streams.find((s: any) => s.agentType === provider.type);
77
77
  if (stream) {
78
78
  h.historyWriter.appendNewMessages(
@@ -197,8 +197,8 @@ export async function handleSendChat(h: CommandHelpers, args: any): Promise<Comm
197
197
  _log(`Extension script error: ${e.message}`);
198
198
  }
199
199
  // Method 2: AgentStreamManager
200
- if (h.agentStream && h.getCdp()) {
201
- const ok = await h.agentStream.sendToAgent(h.getCdp()!, provider.type, text, h.currentIdeType);
200
+ if (h.agentStream && h.getCdp() && h.currentIdeType) {
201
+ const ok = await h.agentStream.sendToAgent(h.getCdp()!, h.currentIdeType, provider.type, text, h.currentIdeType);
202
202
  if (ok) {
203
203
  _log(`AgentStreamManager sent OK`);
204
204
  return _logSendSuccess('agent-stream');
@@ -318,9 +318,9 @@ export async function handleListChats(h: CommandHelpers, args: any): Promise<Com
318
318
  const provider = h.getProvider(args?.agentType);
319
319
 
320
320
  // Extension: via AgentStreamManager
321
- if (provider?.category === 'extension' && h.agentStream && h.getCdp()) {
321
+ if (provider?.category === 'extension' && h.agentStream && h.getCdp() && h.currentIdeType) {
322
322
  try {
323
- const chats = await h.agentStream.listAgentChats(h.getCdp()!, provider.type);
323
+ const chats = await h.agentStream.listAgentChats(h.getCdp()!, h.currentIdeType, provider.type);
324
324
  LOG.info('Command', `[list_chats] Extension: ${chats.length} chats`);
325
325
  return { success: true, chats };
326
326
  } catch (e: any) {
@@ -377,8 +377,8 @@ export async function handleNewChat(h: CommandHelpers, args: any): Promise<Comma
377
377
  return { success: false, error: 'new_chat not supported by this CLI provider' };
378
378
  }
379
379
 
380
- if (provider?.category === 'extension' && h.agentStream && h.getCdp()) {
381
- const ok = await h.agentStream.newAgentSession(h.getCdp()!, provider.type, h.currentIdeType);
380
+ if (provider?.category === 'extension' && h.agentStream && h.getCdp() && h.currentIdeType) {
381
+ const ok = await h.agentStream.newAgentSession(h.getCdp()!, h.currentIdeType, provider.type, h.currentIdeType);
382
382
  return { success: ok };
383
383
  }
384
384
 
@@ -412,8 +412,8 @@ export async function handleSwitchChat(h: CommandHelpers, args: any): Promise<Co
412
412
  if (!sessionId) return { success: false, error: 'sessionId required' };
413
413
  LOG.info('Command', `[switch_chat] sessionId=${sessionId}, ideType=${ideType}`);
414
414
 
415
- if (provider?.category === 'extension' && h.agentStream && h.getCdp()) {
416
- const ok = await h.agentStream.switchAgentSession(h.getCdp()!, provider.type, sessionId);
415
+ if (provider?.category === 'extension' && h.agentStream && h.getCdp() && h.currentIdeType) {
416
+ const ok = await h.agentStream.switchAgentSession(h.getCdp()!, h.currentIdeType, provider.type, sessionId);
417
417
  return { success: ok, result: ok ? 'switched' : 'failed' };
418
418
  }
419
419
 
@@ -681,9 +681,9 @@ export async function handleResolveAction(h: CommandHelpers, args: any): Promise
681
681
  }
682
682
 
683
683
  // 1. Extension: via AgentStreamManager
684
- if (provider?.category === 'extension' && h.agentStream && h.getCdp()) {
684
+ if (provider?.category === 'extension' && h.agentStream && h.getCdp() && h.currentIdeType) {
685
685
  const ok = await h.agentStream.resolveAgentAction(
686
- h.getCdp()!, provider.type, action, h.currentIdeType
686
+ h.getCdp()!, h.currentIdeType, provider.type, action, h.currentIdeType
687
687
  );
688
688
  return { success: ok };
689
689
  }
@@ -97,7 +97,7 @@ export class DaemonCommandHandler implements CommandHelpers {
97
97
  // 1. Try instanceIdMap (UUID → managerKey)
98
98
  const resolved = this._ctx.instanceIdMap?.get(key) || key;
99
99
  // 2. Use findCdpManager (exact + prefix match)
100
- const m = findCdpManager(this._ctx.cdpManagers, resolved.toLowerCase());
100
+ const m = findCdpManager(this._ctx.cdpManagers, resolved);
101
101
  if (m?.isConnected) return m;
102
102
  return null;
103
103
  }
@@ -148,11 +148,11 @@ export class DaemonCommandHandler implements CommandHelpers {
148
148
 
149
149
  // Extension: evaluateInSession
150
150
  if (provider?.category === 'extension') {
151
- let sessionId = this.getExtensionSessionId(provider);
152
- if (!sessionId && this._agentStream) {
153
- await this._agentStream.switchActiveAgent(cdp, provider.type);
154
- await this._agentStream.syncAgentSessions(cdp);
155
- sessionId = this.getExtensionSessionId(provider);
151
+ let sessionId = this.getExtensionSessionId(provider, this._currentIdeType);
152
+ if (!sessionId && this._agentStream && this._currentIdeType) {
153
+ await this._agentStream.switchActiveAgent(cdp, this._currentIdeType, provider.type);
154
+ await this._agentStream.syncAgentSessions(cdp, this._currentIdeType);
155
+ sessionId = this.getExtensionSessionId(provider, this._currentIdeType);
156
156
  }
157
157
  if (!sessionId) return null;
158
158
  const result = await cdp.evaluateInSessionFrame(sessionId, script, timeout);
@@ -194,18 +194,48 @@ export class DaemonCommandHandler implements CommandHelpers {
194
194
 
195
195
  // ─── Private helpers ──────────────────────────────
196
196
 
197
- private getExtensionSessionId(provider: ProviderModule): string | null {
198
- if (provider.category !== 'extension' || !this._agentStream) return null;
199
- const managed = this._agentStream.getManagedAgent(provider.type);
197
+ private getExtensionSessionId(provider: ProviderModule, scopeKey?: string): string | null {
198
+ if (provider.category !== 'extension' || !this._agentStream || !scopeKey) return null;
199
+ const managed = this._agentStream.getManagedAgent(provider.type, scopeKey);
200
200
  return managed?.sessionId || null;
201
201
  }
202
202
 
203
+ private resolveManagerKeyFromInstanceId(instanceId: string): string | undefined {
204
+ const mapped = this._ctx.instanceIdMap?.get(instanceId);
205
+ if (mapped) return mapped;
206
+
207
+ const entries = (this._ctx.instanceManager as any)?.instances?.entries?.();
208
+ if (!entries) return undefined;
209
+
210
+ for (const [instanceKey, instance] of entries as Iterable<[string, any]>) {
211
+ if (typeof instanceKey !== 'string' || !instanceKey.startsWith('ide:')) continue;
212
+
213
+ if (typeof instance?.getInstanceId === 'function' && instance.getInstanceId() === instanceId) {
214
+ const managerKey = instanceKey.slice(4);
215
+ this._ctx.instanceIdMap?.set(instanceId, managerKey);
216
+ return managerKey;
217
+ }
218
+
219
+ if (typeof instance?.getExtensionInstances === 'function') {
220
+ for (const ext of instance.getExtensionInstances() || []) {
221
+ if (typeof ext?.getInstanceId === 'function' && ext.getInstanceId() === instanceId) {
222
+ const managerKey = instanceKey.slice(4);
223
+ this._ctx.instanceIdMap?.set(instanceId, managerKey);
224
+ return managerKey;
225
+ }
226
+ }
227
+ }
228
+ }
229
+
230
+ return undefined;
231
+ }
232
+
203
233
  /** Extract ideType from _targetInstance or explicit ideType */
204
234
  private extractIdeType(args: any): string | undefined {
205
235
  // Also accept explicit ideType from args (P2P input, agentType for extensions)
206
236
  if (args?.ideType) {
207
237
  // UUID → managerKey via instanceIdMap (P2P sends UUID instance IDs)
208
- const mappedKey = this._ctx.instanceIdMap?.get(args.ideType);
238
+ const mappedKey = this.resolveManagerKeyFromInstanceId(args.ideType);
209
239
  if (mappedKey) {
210
240
  return mappedKey;
211
241
  }
@@ -232,8 +262,9 @@ export class DaemonCommandHandler implements CommandHelpers {
232
262
  else if (cliMatch) raw = cliMatch[1];
233
263
  else if (acpMatch) raw = acpMatch[1];
234
264
 
235
- if (this._ctx.instanceIdMap?.has(raw)) {
236
- return this._ctx.instanceIdMap.get(raw)!;
265
+ const mappedKey = this.resolveManagerKeyFromInstanceId(raw);
266
+ if (mappedKey) {
267
+ return mappedKey;
237
268
  }
238
269
 
239
270
  // Direct CDP manager key match (e.g. "cursor", "cursor_remote_vs")
@@ -11,15 +11,15 @@ import { LOG } from '../logging/logger.js';
11
11
  // ─── Agent Stream commands ───────────────────────
12
12
 
13
13
  export async function handleAgentStreamSwitch(h: CommandHelpers, args: any): Promise<CommandResult> {
14
- if (!h.agentStream || !h.getCdp()) return { success: false, error: 'AgentStream or CDP not available' };
14
+ if (!h.agentStream || !h.getCdp() || !h.currentIdeType) return { success: false, error: 'AgentStream or CDP not available' };
15
15
  const agentType = args?.agentType || args?.agent || null;
16
- await h.agentStream.switchActiveAgent(h.getCdp()!, agentType);
16
+ await h.agentStream.switchActiveAgent(h.getCdp()!, h.currentIdeType, agentType);
17
17
  return { success: true, activeAgent: agentType };
18
18
  }
19
19
 
20
20
  export async function handleAgentStreamRead(h: CommandHelpers, args: any): Promise<CommandResult> {
21
- if (!h.agentStream || !h.getCdp()) return { success: false, error: 'AgentStream or CDP not available' };
22
- const streams = await h.agentStream.collectAgentStreams(h.getCdp()!);
21
+ if (!h.agentStream || !h.getCdp() || !h.currentIdeType) return { success: false, error: 'AgentStream or CDP not available' };
22
+ const streams = await h.agentStream.collectAgentStreams(h.getCdp()!, h.currentIdeType);
23
23
  return { success: true, streams };
24
24
  }
25
25
 
@@ -46,52 +46,58 @@ export async function handleAgentStreamSend(h: CommandHelpers, args: any): Promi
46
46
 
47
47
  // CDP-based IDE agent routing
48
48
  if (!h.agentStream || !h.getCdp()) return { success: false, error: 'AgentStream or CDP not available' };
49
- const resolvedAgent = agentType || h.agentStream.activeAgentType;
49
+ const resolvedAgent = agentType || (h.currentIdeType ? h.agentStream.getActiveAgentType(h.currentIdeType) : null);
50
50
  if (!resolvedAgent) return { success: false, error: 'agentType required' };
51
- const ok = await h.agentStream.sendToAgent(h.getCdp()!, resolvedAgent, text, h.currentIdeType);
51
+ if (!h.currentIdeType) return { success: false, error: 'ideType required' };
52
+ const ok = await h.agentStream.sendToAgent(h.getCdp()!, h.currentIdeType, resolvedAgent, text, h.currentIdeType);
52
53
  return { success: ok };
53
54
  }
54
55
 
55
56
  export async function handleAgentStreamResolve(h: CommandHelpers, args: any): Promise<CommandResult> {
56
57
  if (!h.agentStream || !h.getCdp()) return { success: false, error: 'AgentStream or CDP not available' };
57
- const agentType = args?.agentType || args?.agent || h.agentStream.activeAgentType;
58
+ const agentType = args?.agentType || args?.agent || (h.currentIdeType ? h.agentStream.getActiveAgentType(h.currentIdeType) : null);
58
59
  const action = args?.action as 'approve' | 'reject' || 'approve';
59
60
  if (!agentType) return { success: false, error: 'agentType required' };
60
- const ok = await h.agentStream.resolveAgentAction(h.getCdp()!, agentType, action, h.currentIdeType);
61
+ if (!h.currentIdeType) return { success: false, error: 'ideType required' };
62
+ const ok = await h.agentStream.resolveAgentAction(h.getCdp()!, h.currentIdeType, agentType, action, h.currentIdeType);
61
63
  return { success: ok };
62
64
  }
63
65
 
64
66
  export async function handleAgentStreamNew(h: CommandHelpers, args: any): Promise<CommandResult> {
65
67
  if (!h.agentStream || !h.getCdp()) return { success: false, error: 'AgentStream or CDP not available' };
66
- const agentType = args?.agentType || args?.agent || h.agentStream.activeAgentType;
68
+ const agentType = args?.agentType || args?.agent || (h.currentIdeType ? h.agentStream.getActiveAgentType(h.currentIdeType) : null);
67
69
  if (!agentType) return { success: false, error: 'agentType required' };
68
- const ok = await h.agentStream.newAgentSession(h.getCdp()!, agentType, h.currentIdeType);
70
+ if (!h.currentIdeType) return { success: false, error: 'ideType required' };
71
+ const ok = await h.agentStream.newAgentSession(h.getCdp()!, h.currentIdeType, agentType, h.currentIdeType);
69
72
  return { success: ok };
70
73
  }
71
74
 
72
75
  export async function handleAgentStreamListChats(h: CommandHelpers, args: any): Promise<CommandResult> {
73
76
  if (!h.agentStream || !h.getCdp()) return { success: false, error: 'AgentStream or CDP not available' };
74
- const agentType = args?.agentType || args?.agent || h.agentStream.activeAgentType;
77
+ const agentType = args?.agentType || args?.agent || (h.currentIdeType ? h.agentStream.getActiveAgentType(h.currentIdeType) : null);
75
78
  if (!agentType) return { success: false, error: 'agentType required' };
76
- const chats = await h.agentStream.listAgentChats(h.getCdp()!, agentType);
79
+ if (!h.currentIdeType) return { success: false, error: 'ideType required' };
80
+ const chats = await h.agentStream.listAgentChats(h.getCdp()!, h.currentIdeType, agentType);
77
81
  return { success: true, chats };
78
82
  }
79
83
 
80
84
  export async function handleAgentStreamSwitchSession(h: CommandHelpers, args: any): Promise<CommandResult> {
81
85
  if (!h.agentStream || !h.getCdp()) return { success: false, error: 'AgentStream or CDP not available' };
82
- const agentType = args?.agentType || args?.agent || h.agentStream.activeAgentType;
86
+ const agentType = args?.agentType || args?.agent || (h.currentIdeType ? h.agentStream.getActiveAgentType(h.currentIdeType) : null);
83
87
  const sessionId = args?.sessionId || args?.id;
84
88
  if (!agentType || !sessionId) return { success: false, error: 'agentType and sessionId required' };
85
- const ok = await h.agentStream.switchAgentSession(h.getCdp()!, agentType, sessionId);
89
+ if (!h.currentIdeType) return { success: false, error: 'ideType required' };
90
+ const ok = await h.agentStream.switchAgentSession(h.getCdp()!, h.currentIdeType, agentType, sessionId);
86
91
  return { success: ok };
87
92
  }
88
93
 
89
94
  export async function handleAgentStreamFocus(h: CommandHelpers, args: any): Promise<CommandResult> {
90
95
  if (!h.agentStream || !h.getCdp()) return { success: false, error: 'AgentStream or CDP not available' };
91
- const agentType = args?.agentType || args?.agent || h.agentStream.activeAgentType;
96
+ const agentType = args?.agentType || args?.agent || (h.currentIdeType ? h.agentStream.getActiveAgentType(h.currentIdeType) : null);
92
97
  if (!agentType) return { success: false, error: 'agentType required' };
93
98
  await h.agentStream.ensureAgentPanelOpen(agentType, h.currentIdeType);
94
- const ok = await h.agentStream.focusAgentEditor(h.getCdp()!, agentType);
99
+ if (!h.currentIdeType) return { success: false, error: 'ideType required' };
100
+ const ok = await h.agentStream.focusAgentEditor(h.getCdp()!, h.currentIdeType, agentType);
95
101
  return { success: ok };
96
102
  }
97
103
 
package/src/index.ts CHANGED
@@ -76,6 +76,8 @@ export type { CommandRouterDeps, CommandRouterResult } from './commands/router.j
76
76
  export { DaemonStatusReporter } from './status/reporter.js';
77
77
  export { buildManagedIdes, buildManagedClis, buildManagedAcps, buildAllManagedEntries, findCdpManager, hasCdpManager, isCdpConnected } from './status/builders.js';
78
78
  export { buildStatusSnapshot } from './status/snapshot.js';
79
+ export { normalizeManagedStatus, isManagedStatusWorking, isManagedStatusWaiting, normalizeActiveChatData } from './status/normalize.js';
80
+ export type { ManagedStatus } from './status/normalize.js';
79
81
  export type { StatusSnapshotOptions, StatusSnapshot } from './status/snapshot.js';
80
82
 
81
83
  // ── Logger ──
@@ -16,6 +16,7 @@ import type {
16
16
  AcpProviderState,
17
17
  ProviderState,
18
18
  } from '../providers/provider-instance.js';
19
+ import { normalizeActiveChatData, normalizeManagedStatus } from './normalize.js';
19
20
 
20
21
  // ─── CDP Manager lookup helpers ──────────────────────
21
22
 
@@ -100,13 +101,13 @@ export function buildManagedIdes(
100
101
  workspace: state.workspace || null,
101
102
  terminals: 0,
102
103
  aiAgents: [],
103
- activeChat: state.activeChat,
104
+ activeChat: normalizeActiveChatData(state.activeChat),
104
105
  chats: [],
105
106
  agentStreams: state.extensions.map((ext) => ({
106
107
  agentType: ext.type,
107
108
  agentName: ext.name,
108
109
  extensionId: ext.type,
109
- status: ext.status || 'idle',
110
+ status: normalizeManagedStatus(ext.status, { activeModal: ext.activeChat?.activeModal || null }),
110
111
  messages: ext.activeChat?.messages || [],
111
112
  inputContent: ext.activeChat?.inputContent || '',
112
113
  activeModal: ext.activeChat?.activeModal || null,
@@ -155,10 +156,10 @@ export function buildManagedClis(
155
156
  instanceId: s.instanceId,
156
157
  cliType: s.type,
157
158
  cliName: s.name,
158
- status: s.status,
159
+ status: normalizeManagedStatus(s.status, { activeModal: s.activeChat?.activeModal || null }),
159
160
  mode: 'terminal' as const,
160
161
  workspace: s.workspace || '',
161
- activeChat: s.activeChat,
162
+ activeChat: normalizeActiveChatData(s.activeChat),
162
163
  }));
163
164
  }
164
165
 
@@ -172,10 +173,10 @@ export function buildManagedAcps(
172
173
  id: s.instanceId,
173
174
  acpType: s.type,
174
175
  acpName: s.name,
175
- status: s.status,
176
+ status: normalizeManagedStatus(s.status, { activeModal: s.activeChat?.activeModal || null }),
176
177
  mode: 'chat' as const,
177
178
  workspace: s.workspace || '',
178
- activeChat: s.activeChat,
179
+ activeChat: normalizeActiveChatData(s.activeChat),
179
180
  currentModel: s.currentModel,
180
181
  currentPlan: s.currentPlan,
181
182
  acpConfigOptions: s.acpConfigOptions,
@@ -0,0 +1,64 @@
1
+ import type { ActiveChatData } from '../providers/provider-instance.js';
2
+
3
+ export type ManagedStatus =
4
+ | 'idle'
5
+ | 'generating'
6
+ | 'waiting_approval'
7
+ | 'error'
8
+ | 'stopped'
9
+ | 'starting'
10
+ | 'panel_hidden'
11
+ | 'not_monitored'
12
+ | 'disconnected';
13
+
14
+ const WORKING_STATUSES = new Set([
15
+ 'generating',
16
+ 'streaming',
17
+ 'loading',
18
+ 'loading_reference',
19
+ 'thinking',
20
+ 'active',
21
+ ]);
22
+
23
+ function hasApprovalButtons(activeModal?: { buttons?: unknown[] | null } | null): boolean {
24
+ return (activeModal?.buttons?.length ?? 0) > 0;
25
+ }
26
+
27
+ export function normalizeManagedStatus(
28
+ status?: string | null,
29
+ opts?: { activeModal?: { buttons?: unknown[] | null } | null },
30
+ ): ManagedStatus {
31
+ if (hasApprovalButtons(opts?.activeModal)) return 'waiting_approval';
32
+
33
+ const normalized = String(status || 'idle').trim().toLowerCase();
34
+ if (normalized === 'waiting_approval') return 'waiting_approval';
35
+ if (WORKING_STATUSES.has(normalized)) return 'generating';
36
+ if (normalized === 'error') return 'error';
37
+ if (normalized === 'stopped') return 'stopped';
38
+ if (normalized === 'starting') return 'starting';
39
+ if (normalized === 'panel_hidden') return 'panel_hidden';
40
+ if (normalized === 'not_monitored') return 'not_monitored';
41
+ if (normalized === 'disconnected') return 'disconnected';
42
+ return 'idle';
43
+ }
44
+
45
+ export function isManagedStatusWorking(status?: string | null): boolean {
46
+ return normalizeManagedStatus(status) === 'generating';
47
+ }
48
+
49
+ export function isManagedStatusWaiting(
50
+ status?: string | null,
51
+ opts?: { activeModal?: { buttons?: unknown[] | null } | null },
52
+ ): boolean {
53
+ return normalizeManagedStatus(status, opts) === 'waiting_approval';
54
+ }
55
+
56
+ export function normalizeActiveChatData<T extends ActiveChatData | null | undefined>(
57
+ activeChat: T,
58
+ ): T {
59
+ if (!activeChat) return activeChat;
60
+ return {
61
+ ...activeChat,
62
+ status: normalizeManagedStatus(activeChat.status, { activeModal: activeChat.activeModal }),
63
+ } as T;
64
+ }