@adhdev/daemon-core 0.7.3 → 0.7.5

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.3",
3
+ "version": "0.7.5",
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",
@@ -185,7 +185,7 @@ export async function initDaemonComponents(config: DaemonInitConfig): Promise<Da
185
185
 
186
186
  if (ideInstance) {
187
187
  instanceManager.removeInstance(instanceKey);
188
- LOG.info('CDP', `Instance removed after disconnect: ${instanceKey}`);
188
+ LOG.info('IDE', `Instance removed after detach: ${instanceKey}`);
189
189
  }
190
190
 
191
191
  if (ideInstance?.getInstanceId) {
@@ -78,9 +78,9 @@ export class DaemonCdpInitializer {
78
78
 
79
79
  // Summary
80
80
  if (cdpManagers.size > 0) {
81
- LOG.info('CDP', `${cdpManagers.size} IDE(s) connected: ${[...cdpManagers.entries()].map(([k, m]) => `${k}:${m.getPort()}`).join(', ')}`);
81
+ LOG.info('IDE', `${cdpManagers.size} IDE window(s) attached: ${[...cdpManagers.entries()].map(([k, m]) => `${k}:${m.getPort()}`).join(', ')}`);
82
82
  } else {
83
- LOG.warn('CDP', `No IDEs connected — tried: ${filtered.map(p => `${p.ide}:${p.port}`).join(', ')}`);
83
+ LOG.warn('IDE', `No IDE windows attached — tried: ${filtered.map(p => `${p.ide}:${p.port}`).join(', ')}`);
84
84
  }
85
85
  }
86
86
 
@@ -113,7 +113,7 @@ export class DaemonCdpInitializer {
113
113
  if (connected) {
114
114
  registerExtensionProviders(providerLoader, manager, ide);
115
115
  cdpManagers.set(ide, manager);
116
- LOG.info('CDP', `Connected: ${ide} (port ${port})`);
116
+ LOG.info('IDE', `Attached: ${ide} (port ${port})`);
117
117
  await this.config.onConnected?.(ide, manager, ide);
118
118
  }
119
119
  return;
@@ -155,7 +155,7 @@ export class DaemonCdpInitializer {
155
155
  if (connected) {
156
156
  registerExtensionProviders(providerLoader, manager, ide);
157
157
  cdpManagers.set(managerKey, manager);
158
- LOG.info('CDP', `Connected: ${managerKey} (port ${port}${targets.length > 1 ? `, page "${target.title}"` : ''})`);
158
+ LOG.info('IDE', `Attached window: ${managerKey} (port ${port}${targets.length > 1 ? `, page "${target.title}"` : ''})`);
159
159
  await this.config.onConnected?.(ide, manager, managerKey);
160
160
  }
161
161
  }
@@ -195,7 +195,7 @@ export class DaemonCdpInitializer {
195
195
  for (const { key, manager, reason } of removals) {
196
196
  try { manager.disconnect(); } catch { /* noop */ }
197
197
  this.config.cdpManagers.delete(key);
198
- LOG.info('CDP', `Removed stale manager: ${key} (${reason})`);
198
+ LOG.info('IDE', `Detached window: ${key} (${reason})`);
199
199
  await this.config.onDisconnected?.(ide, manager, key, reason);
200
200
  }
201
201
  }
@@ -134,7 +134,7 @@ export class DaemonCdpScanner {
134
134
 
135
135
  registerExtensionProviders(this.ctx.providerLoader, manager, ide);
136
136
  this.ctx.cdpManagers.set(ide, manager);
137
- LOG.info('CDP', `Connected: ${ide} (port ${port})`);
137
+ LOG.info('IDE', `Attached: ${ide} (port ${port})`);
138
138
 
139
139
  // Setup IDE instance
140
140
  await setupIdeInstance(this.ctx, { ideType: ide, manager });
@@ -172,7 +172,7 @@ export class DaemonCdpScanner {
172
172
  if (!manager) continue;
173
173
 
174
174
  this.ctx.cdpManagers.set(managerKey, manager);
175
- LOG.info('CDP', `Connected: ${managerKey} (port ${port}, page "${target.title}")`);
175
+ LOG.info('IDE', `Attached window: ${managerKey} (port ${port}, page "${target.title}")`);
176
176
 
177
177
  await setupIdeInstance(this.ctx, {
178
178
  ideType: ide,
@@ -65,6 +65,96 @@ export interface CommandHelpers {
65
65
  readonly historyWriter: ChatHistoryWriter;
66
66
  }
67
67
 
68
+ const COMMAND_DEBUG_LEVELS = new Set([
69
+ 'pty_input',
70
+ 'pty_resize',
71
+ 'cdp_eval',
72
+ 'cdp_batch',
73
+ 'cdp_dom_query',
74
+ 'cdp_dom_dump',
75
+ 'cdp_dom_debug',
76
+ ]);
77
+
78
+ function logAtLevel(level: 'debug' | 'info' | 'warn' | 'error', category: string, message: string): void {
79
+ switch (level) {
80
+ case 'debug':
81
+ LOG.debug(category, message);
82
+ return;
83
+ case 'warn':
84
+ LOG.warn(category, message);
85
+ return;
86
+ case 'error':
87
+ LOG.error(category, message);
88
+ return;
89
+ default:
90
+ LOG.info(category, message);
91
+ }
92
+ }
93
+
94
+ function getCommandLogLevel(cmd: string): 'debug' | 'info' {
95
+ return COMMAND_DEBUG_LEVELS.has(cmd) ? 'debug' : 'info';
96
+ }
97
+
98
+ function summarizeLogValue(value: unknown): string {
99
+ if (value === null) return 'null';
100
+ if (value === undefined) return 'undefined';
101
+ if (typeof value === 'string') {
102
+ const normalized = value.replace(/\s+/g, ' ').trim();
103
+ if (!normalized) return '""';
104
+ if (normalized.length <= 80) return JSON.stringify(normalized);
105
+ return `${JSON.stringify(normalized.slice(0, 80))}…(${normalized.length} chars)`;
106
+ }
107
+ if (typeof value === 'number' || typeof value === 'boolean') return String(value);
108
+ if (Array.isArray(value)) return `[${value.length} items]`;
109
+ if (typeof value === 'object') return '{...}';
110
+ return String(value);
111
+ }
112
+
113
+ function summarizeCommandArgs(args: any): string {
114
+ if (!args || typeof args !== 'object') return '-';
115
+
116
+ const preferredKeys = [
117
+ 'targetSessionId',
118
+ 'providerType',
119
+ 'agentType',
120
+ 'ideType',
121
+ 'model',
122
+ 'mode',
123
+ 'action',
124
+ 'button',
125
+ 'key',
126
+ 'force',
127
+ 'offset',
128
+ 'limit',
129
+ 'cols',
130
+ 'rows',
131
+ 'path',
132
+ 'command',
133
+ 'commandId',
134
+ 'workspace',
135
+ 'dir',
136
+ 'url',
137
+ 'text',
138
+ 'message',
139
+ 'data',
140
+ 'value',
141
+ ];
142
+
143
+ const entries: string[] = [];
144
+ for (const key of preferredKeys) {
145
+ if (!(key in args) || args[key] === undefined) continue;
146
+ const value =
147
+ key === 'text' || key === 'message'
148
+ ? `${String(args[key] || '').length} chars`
149
+ : key === 'data'
150
+ ? `${String(args[key] || '').length} chars`
151
+ : summarizeLogValue(args[key]);
152
+ entries.push(`${key}=${value}`);
153
+ }
154
+
155
+ return entries.length ? entries.join(' ') : '{...}';
156
+ }
157
+
68
158
  export class DaemonCommandHandler implements CommandHelpers {
69
159
  private _ctx: CommandContext;
70
160
  private _agentStream: DaemonAgentStreamManager | null = null;
@@ -235,6 +325,30 @@ export class DaemonCommandHandler implements CommandHelpers {
235
325
  return undefined;
236
326
  }
237
327
 
328
+ private logCommandStart(cmd: string, args: any): void {
329
+ const routeBits = [
330
+ this._currentRoute.session?.sessionId ? `session=${this._currentRoute.session.sessionId}` : '',
331
+ this._currentRoute.managerKey ? `manager=${this._currentRoute.managerKey}` : '',
332
+ this._currentRoute.providerType ? `provider=${this._currentRoute.providerType}` : '',
333
+ ].filter(Boolean).join(' ');
334
+ const summary = summarizeCommandArgs(args);
335
+ logAtLevel(
336
+ getCommandLogLevel(cmd),
337
+ 'Command',
338
+ `[${cmd}] start${routeBits ? ` ${routeBits}` : ''} args=${summary}`,
339
+ );
340
+ }
341
+
342
+ private logCommandEnd(cmd: string, result: CommandResult, startedAt: number): void {
343
+ const durationMs = Date.now() - startedAt;
344
+ const parts = [`[${cmd}] end`, `success=${result.success}`, `duration=${durationMs}ms`];
345
+ if (typeof result.error === 'string' && result.error) {
346
+ parts.push(`error=${JSON.stringify(result.error)}`);
347
+ }
348
+ const level = result.success ? getCommandLogLevel(cmd) : 'warn';
349
+ logAtLevel(level, 'Command', parts.join(' '));
350
+ }
351
+
238
352
  setAgentStreamManager(manager: DaemonAgentStreamManager): void {
239
353
  this._agentStream = manager;
240
354
  }
@@ -244,20 +358,29 @@ export class DaemonCommandHandler implements CommandHelpers {
244
358
  async handle(cmd: string, args: any): Promise<CommandResult> {
245
359
  // Per-request: extract target session / CDP scope / provider type from args
246
360
  this._currentRoute = this.resolveRoute(args);
361
+ const startedAt = Date.now();
362
+ this.logCommandStart(cmd, args);
247
363
 
248
364
  // Commands without ideType CDP silently fail (prevent P2P retry spam)
365
+ let result: CommandResult;
249
366
  if (!this._currentRoute.session && !this._currentRoute.managerKey && !this._currentRoute.providerType) {
250
367
  const cdpCommands = ['send_chat', 'read_chat', 'list_chats', 'new_chat', 'switch_chat', 'set_mode', 'change_model', 'set_thought_level', 'resolve_action'];
251
368
  if (cdpCommands.includes(cmd)) {
252
- return { success: false, error: 'No targetSessionId specified — cannot route command' };
369
+ result = { success: false, error: 'No targetSessionId specified — cannot route command' };
370
+ this.logCommandEnd(cmd, result, startedAt);
371
+ return result;
253
372
  }
254
373
  }
255
374
 
256
375
  try {
257
- return await this.dispatch(cmd, args);
376
+ result = await this.dispatch(cmd, args);
377
+ this.logCommandEnd(cmd, result, startedAt);
378
+ return result;
258
379
  } catch (e: any) {
259
380
  LOG.error('Command', `[${cmd}] Unhandled error: ${e?.message || e}`);
260
- return { success: false, error: `Internal error: ${e?.message || 'unknown'}` };
381
+ result = { success: false, error: `Internal error: ${e?.message || 'unknown'}` };
382
+ this.logCommandEnd(cmd, result, startedAt);
383
+ return result;
261
384
  }
262
385
  }
263
386
 
@@ -85,7 +85,6 @@ export function handleSetProviderSetting(h: CommandHelpers, args: any): CommandR
85
85
 
86
86
  export async function handleExtensionScript(h: CommandHelpers, args: any, scriptName: string): Promise<CommandResult> {
87
87
  const { agentType, ideType } = args || {};
88
- LOG.info('Command', `[ExtScript] ${scriptName} agentType=${agentType} ideType=${ideType} session=${h.currentSession?.sessionId || ''}`);
89
88
  if (!agentType) return { success: false, error: 'agentType is required' };
90
89
 
91
90
  const loader = h.ctx.providerLoader;