@adhdev/daemon-core 0.8.30 → 0.8.31

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.
Files changed (57) hide show
  1. package/dist/agent-stream/manager.d.ts +1 -0
  2. package/dist/agent-stream/provider-adapter.d.ts +1 -0
  3. package/dist/agent-stream/types.d.ts +3 -0
  4. package/dist/boot/daemon-lifecycle.d.ts +2 -1
  5. package/dist/cdp/manager.d.ts +2 -0
  6. package/dist/cli-adapter-types.d.ts +34 -5
  7. package/dist/cli-adapters/provider-cli-adapter.d.ts +4 -158
  8. package/dist/cli-adapters/provider-cli-config.d.ts +30 -0
  9. package/dist/cli-adapters/provider-cli-parse.d.ts +42 -0
  10. package/dist/cli-adapters/provider-cli-runtime.d.ts +29 -0
  11. package/dist/cli-adapters/provider-cli-shared.d.ts +158 -0
  12. package/dist/commands/handler.d.ts +4 -3
  13. package/dist/config/config.d.ts +4 -3
  14. package/dist/index.js +866 -592
  15. package/dist/index.js.map +1 -1
  16. package/dist/index.mjs +868 -595
  17. package/dist/index.mjs.map +1 -1
  18. package/dist/providers/contracts.d.ts +10 -1
  19. package/dist/providers/provider-loader.d.ts +3 -0
  20. package/dist/status/reporter.d.ts +2 -3
  21. package/dist/status/snapshot.d.ts +2 -1
  22. package/node_modules/@adhdev/session-host-core/package.json +1 -1
  23. package/package.json +3 -1
  24. package/src/agent-stream/manager.ts +8 -2
  25. package/src/agent-stream/poller.ts +19 -5
  26. package/src/agent-stream/provider-adapter.ts +11 -7
  27. package/src/agent-stream/types.ts +3 -0
  28. package/src/boot/daemon-lifecycle.ts +7 -6
  29. package/src/cdp/initializer.ts +2 -2
  30. package/src/cdp/manager.ts +5 -0
  31. package/src/cdp/setup.ts +1 -1
  32. package/src/cli-adapter-types.ts +37 -5
  33. package/src/cli-adapters/provider-cli-adapter.ts +212 -795
  34. package/src/cli-adapters/provider-cli-config.ts +66 -0
  35. package/src/cli-adapters/provider-cli-parse.ts +202 -0
  36. package/src/cli-adapters/provider-cli-runtime.ts +142 -0
  37. package/src/cli-adapters/provider-cli-shared.ts +439 -0
  38. package/src/cli-adapters/terminal-backends/ghostty-vt-backend.ts +1 -1
  39. package/src/commands/cdp-commands.ts +6 -1
  40. package/src/commands/chat-commands.ts +45 -29
  41. package/src/commands/cli-manager.ts +28 -9
  42. package/src/commands/handler.ts +14 -10
  43. package/src/commands/router.ts +23 -10
  44. package/src/commands/stream-commands.ts +11 -5
  45. package/src/config/config.ts +4 -10
  46. package/src/daemon/dev-auto-implement.ts +22 -18
  47. package/src/daemon/dev-cli-debug.ts +59 -16
  48. package/src/daemon/dev-server.ts +67 -43
  49. package/src/providers/acp-provider-instance.ts +1 -1
  50. package/src/providers/cli-provider-instance.ts +2 -2
  51. package/src/providers/contracts.ts +12 -1
  52. package/src/providers/extension-provider-instance.ts +1 -1
  53. package/src/providers/ide-provider-instance.ts +39 -18
  54. package/src/providers/provider-loader.ts +85 -54
  55. package/src/providers/version-archive.ts +23 -5
  56. package/src/status/reporter.ts +18 -14
  57. package/src/status/snapshot.ts +5 -4
@@ -20,7 +20,7 @@ import * as fs from 'fs';
20
20
  import * as path from 'path';
21
21
  import * as os from 'os';
22
22
  import type { ProviderLoader } from '../providers/provider-loader.js';
23
- import type { ProviderCategory } from '../providers/contracts.js';
23
+ import type { ProviderCategory, ProviderModule, ProviderScripts, ProviderSettingDef } from '../providers/contracts.js';
24
24
  import type { ChildProcess } from 'child_process';
25
25
  import type { DaemonCdpManager } from '../cdp/manager.js';
26
26
  import type { ProviderInstanceManager } from '../providers/provider-instance-manager.js';
@@ -34,6 +34,64 @@ import { handleAutoImplement, handleAutoImplCancel, handleAutoImplSSE } from './
34
34
 
35
35
  export const DEV_SERVER_PORT = 19280;
36
36
 
37
+ interface ProviderListEntry {
38
+ type: string;
39
+ name: string;
40
+ category: ProviderCategory;
41
+ icon: string | null;
42
+ displayName: string;
43
+ scripts?: string[];
44
+ inputMethod?: ProviderModule['inputMethod'] | null;
45
+ inputSelector?: string | null;
46
+ extensionId?: string | null;
47
+ cdpPorts?: [number, number] | [];
48
+ spawn?: ProviderModule['spawn'] | null;
49
+ auth?: ProviderModule['auth'] | null;
50
+ install?: string | null;
51
+ hasSettings?: boolean;
52
+ settingsCount?: number;
53
+ }
54
+
55
+ function getScriptNames(scripts?: ProviderScripts): string[] {
56
+ if (!scripts) return [];
57
+ return Object.entries(scripts)
58
+ .filter(([, value]) => typeof value === 'function')
59
+ .map(([name]) => name);
60
+ }
61
+
62
+ function toProviderListEntry(provider: ProviderModule): ProviderListEntry {
63
+ const base: ProviderListEntry = {
64
+ type: provider.type,
65
+ name: provider.name,
66
+ category: provider.category,
67
+ icon: provider.icon || null,
68
+ displayName: provider.displayName || provider.name,
69
+ };
70
+
71
+ if (provider.category === 'ide' || provider.category === 'extension') {
72
+ base.scripts = getScriptNames(provider.scripts);
73
+ base.inputMethod = provider.inputMethod || null;
74
+ base.inputSelector = provider.inputSelector || null;
75
+ base.extensionId = provider.extensionId || null;
76
+ base.cdpPorts = provider.cdpPorts || [];
77
+ }
78
+
79
+ if (provider.category === 'acp') {
80
+ base.spawn = provider.spawn || null;
81
+ base.auth = provider.auth || null;
82
+ base.install = provider.install || null;
83
+ base.hasSettings = !!provider.settings;
84
+ base.settingsCount = provider.settings ? Object.keys(provider.settings).length : 0;
85
+ }
86
+
87
+ if (provider.category === 'cli') {
88
+ base.spawn = provider.spawn || null;
89
+ base.install = provider.install || null;
90
+ }
91
+
92
+ return base;
93
+ }
94
+
37
95
  export class DevServer implements DevServerContext {
38
96
  private server: http.Server | null = null;
39
97
  public providerLoader: ProviderLoader;
@@ -212,41 +270,7 @@ export class DevServer implements DevServerContext {
212
270
  // ─── Handlers ───
213
271
 
214
272
  private async handleListProviders(_req: http.IncomingMessage, res: http.ServerResponse): Promise<void> {
215
- const providers = this.providerLoader.getAll().map(p => {
216
- const base: any = {
217
- type: p.type,
218
- name: p.name,
219
- category: p.category,
220
- icon: (p as any).icon || null,
221
- displayName: (p as any).displayName || p.name,
222
- };
223
-
224
- // IDE/Extension specific
225
- if (p.category === 'ide' || p.category === 'extension') {
226
- base.scripts = p.scripts ? Object.keys(p.scripts).filter(k => typeof (p.scripts as any)[k] === 'function') : [];
227
- base.inputMethod = p.inputMethod || null;
228
- base.inputSelector = (p as any).inputSelector || null;
229
- base.extensionId = p.extensionId || null;
230
- base.cdpPorts = (p as any).cdpPorts || [];
231
- }
232
-
233
- // ACP specific
234
- if (p.category === 'acp') {
235
- base.spawn = (p as any).spawn || null;
236
- base.auth = (p as any).auth || null;
237
- base.install = (p as any).install || null;
238
- base.hasSettings = !!(p as any).settings;
239
- base.settingsCount = (p as any).settings ? Object.keys((p as any).settings).length : 0;
240
- }
241
-
242
- // CLI specific
243
- if (p.category === 'cli') {
244
- base.spawn = (p as any).spawn || null;
245
- base.install = (p as any).install || null;
246
- }
247
-
248
- return base;
249
- });
273
+ const providers = this.providerLoader.getAll().map(toProviderListEntry);
250
274
  this.json(res, 200, { providers, count: providers.length });
251
275
  }
252
276
 
@@ -273,7 +297,7 @@ export class DevServer implements DevServerContext {
273
297
  return;
274
298
  }
275
299
 
276
- const spawn = (provider as any).spawn;
300
+ const spawn = provider.spawn;
277
301
  if (!spawn) {
278
302
  this.json(res, 400, { error: `Provider ${type} has no spawn config` });
279
303
  return;
@@ -330,7 +354,7 @@ export class DevServer implements DevServerContext {
330
354
  return;
331
355
  }
332
356
 
333
- const fn = (provider.scripts as any)?.[scriptName];
357
+ const fn = provider.scripts?.[scriptName];
334
358
  if (typeof fn !== 'function') {
335
359
  this.json(res, 400, { error: `Script '${scriptName}' not found in provider '${type}'`, available: provider.scripts ? Object.keys(provider.scripts) : [] });
336
360
  return;
@@ -446,7 +470,7 @@ export class DevServer implements DevServerContext {
446
470
  }));
447
471
  for (const cdp of this.cdpManagers.values()) {
448
472
  if (!cdp.isConnected) {
449
- (cdp as any)._targetId = null;
473
+ cdp.clearTargetId();
450
474
  }
451
475
  }
452
476
  this.json(res, 200, { reloaded: true, providers });
@@ -569,7 +593,7 @@ export class DevServer implements DevServerContext {
569
593
  this.sendSSE({ type: 'watch_error', error: `Provider '${this.watchScriptPath}' not found` });
570
594
  return;
571
595
  }
572
- const fn = (provider.scripts as any)?.[this.watchScriptName!];
596
+ const fn = provider.scripts?.[this.watchScriptName!];
573
597
  if (typeof fn !== 'function') {
574
598
  this.sendSSE({ type: 'watch_error', error: `Script '${this.watchScriptName}' not found` });
575
599
  return;
@@ -769,7 +793,7 @@ export class DevServer implements DevServerContext {
769
793
  // Settings validation
770
794
  if (config.settings) {
771
795
  for (const [key, val] of Object.entries(config.settings)) {
772
- const s = val as any;
796
+ const s = val as Partial<ProviderSettingDef>;
773
797
  if (!s.type) errors.push(`settings.${key}: missing type`);
774
798
  else if (!['boolean', 'number', 'string', 'select'].includes(s.type))
775
799
  errors.push(`settings.${key}: invalid type '${s.type}'`);
@@ -784,7 +808,7 @@ export class DevServer implements DevServerContext {
784
808
  if (config.cdpPorts && Array.isArray(config.cdpPorts)) {
785
809
  const allProviders = this.providerLoader.getAll();
786
810
  for (const port of config.cdpPorts) {
787
- const conflict = allProviders.find(p => p.type !== type && (p as any).cdpPorts?.includes(port));
811
+ const conflict = allProviders.find(p => p.type !== type && p.cdpPorts?.includes(port));
788
812
  if (conflict) warnings.push(`CDP port ${port} conflicts with provider '${conflict.type}'`);
789
813
  }
790
814
  }
@@ -801,7 +825,7 @@ export class DevServer implements DevServerContext {
801
825
  if (!message) { this.json(res, 400, { error: 'message required' }); return; }
802
826
  const provider = this.providerLoader.getMeta(type);
803
827
  if (!provider) { this.json(res, 404, { error: `Provider not found: ${type}` }); return; }
804
- const spawn = (provider as any).spawn;
828
+ const spawn = provider.spawn;
805
829
  if (!spawn) { this.json(res, 400, { error: `Provider ${type} has no spawn config` }); return; }
806
830
 
807
831
  const { spawn: spawnFn } = await import('child_process');
@@ -232,7 +232,7 @@ export class AcpProviderInstance implements ProviderInstance {
232
232
  ...(this.currentModel ? { model: this.currentModel } : {}),
233
233
  ...(this.currentMode ? { mode: this.currentMode } : {}),
234
234
  },
235
- providerControls: this.provider.controls as any,
235
+ providerControls: this.provider.controls,
236
236
  };
237
237
  }
238
238
 
@@ -101,7 +101,7 @@ export class CliProviderInstance implements ProviderInstance {
101
101
  this.providerSessionId = options?.providerSessionId;
102
102
  this.launchMode = options?.launchMode || 'new';
103
103
  this.onProviderSessionResolved = options?.onProviderSessionResolved;
104
- this.adapter = new ProviderCliAdapter(provider as any as CliProviderModule, workingDir, cliArgs, transportFactory);
104
+ this.adapter = new ProviderCliAdapter(provider as CliProviderModule, workingDir, cliArgs, transportFactory);
105
105
  this.monitor = new StatusMonitor();
106
106
  this.historyWriter = new ChatHistoryWriter();
107
107
  }
@@ -328,7 +328,7 @@ export class CliProviderInstance implements ProviderInstance {
328
328
  } : undefined,
329
329
  resume: this.provider.resume,
330
330
  controlValues: this.controlValues,
331
- providerControls: this.provider.controls as any,
331
+ providerControls: this.provider.controls,
332
332
  };
333
333
  }
334
334
 
@@ -304,6 +304,13 @@ export interface CdpTargetFilter {
304
304
  titleExcludes?: string;
305
305
  }
306
306
 
307
+ export type ProviderVersionCommand = string | Partial<Record<string, string>>;
308
+
309
+ export interface ProviderCompatibilityEntry {
310
+ ideVersion: string;
311
+ scriptDir: string;
312
+ }
313
+
307
314
  export interface ProviderModule {
308
315
  /** Unique identifier (e.g. 'cline', 'cursor', 'gemini-cli') */
309
316
  type: string;
@@ -328,7 +335,7 @@ export interface ProviderModule {
328
335
  /** Install instructions (shown when command is missing) */
329
336
  install?: string;
330
337
  /** Custom version detection command (e.g. 'cursor --version', 'claude -v') */
331
- versionCommand?: string;
338
+ versionCommand?: ProviderVersionCommand;
332
339
  /** Versions tested by provider maintainer (informational) */
333
340
  testedVersions?: string[];
334
341
  /** Per-OS process names — used by launch.ts to detect/kill IDE processes */
@@ -371,6 +378,9 @@ export interface ProviderModule {
371
378
  // ─── Extension category only ───
372
379
  extensionId?: string;
373
380
  extensionIdPattern?: RegExp;
381
+ extensionIdPattern_flags?: string;
382
+ compatibility?: ProviderCompatibilityEntry[];
383
+ defaultScriptDir?: string;
374
384
 
375
385
  // ─── CLI category only ───
376
386
  binary?: string;
@@ -380,6 +390,7 @@ export interface ProviderModule {
380
390
  shell?: boolean;
381
391
  env?: Record<string, string>;
382
392
  };
393
+ approvalKeys?: Record<number, string>;
383
394
  patterns?: {
384
395
  prompt?: RegExp[];
385
396
  generating?: RegExp[];
@@ -92,7 +92,7 @@ export class ExtensionProviderInstance implements ProviderInstance {
92
92
  currentModel: this.currentModel || undefined,
93
93
  currentPlan: this.currentMode || undefined,
94
94
  controlValues: this.controlValues,
95
- providerControls: this.provider.controls as any,
95
+ providerControls: this.provider.controls,
96
96
  agentStreams: this.agentStreams,
97
97
  instanceId: this.instanceId,
98
98
  lastUpdated: Date.now(),
@@ -21,6 +21,24 @@ import { extractProviderControlValues, normalizeProviderEffects } from './contro
21
21
  import type { ChatMessage } from '../types.js';
22
22
  import { formatAutoApprovalMessage, pickApprovalButton } from './approval-utils.js';
23
23
 
24
+ type ReadChatModal = {
25
+ message?: string;
26
+ buttons?: string[];
27
+ width?: number;
28
+ height?: number;
29
+ };
30
+
31
+ type ReadChatMessage = ChatMessage & { content: string };
32
+
33
+ type ReadChatPayload = {
34
+ activeModal?: ReadChatModal;
35
+ messages?: ReadChatMessage[];
36
+ controlValues?: Record<string, string | number | boolean>;
37
+ status?: string;
38
+ title?: string;
39
+ [key: string]: unknown;
40
+ };
41
+
24
42
  export class IdeProviderInstance implements ProviderInstance {
25
43
  readonly type: string;
26
44
  readonly category = 'ide' as const;
@@ -138,7 +156,7 @@ export class IdeProviderInstance implements ProviderInstance {
138
156
  currentPlan: this.cachedChat?.mode || undefined,
139
157
  currentAutoApprove: this.cachedChat?.autoApprove || undefined,
140
158
  controlValues: this.cachedChat?.controlValues || undefined,
141
- providerControls: this.provider.controls as any,
159
+ providerControls: this.provider.controls,
142
160
  instanceId: this.instanceId,
143
161
  lastUpdated: Date.now(),
144
162
  settings: this.settings,
@@ -261,14 +279,14 @@ export class IdeProviderInstance implements ProviderInstance {
261
279
  if (!cdp?.isConnected) return;
262
280
 
263
281
  try {
264
- let raw: any = null;
282
+ let raw: unknown = null;
265
283
 
266
284
  // path 1: webview iframe internal (Kiro, PearAI etc)
267
- const webviewFn = (this.provider.scripts as any)?.webviewReadChat;
285
+ const webviewFn = this.provider.scripts?.webviewReadChat;
268
286
  if (typeof webviewFn === 'function' && cdp.evaluateInWebviewFrame) {
269
287
  const webviewScript = webviewFn();
270
288
  if (webviewScript) {
271
- const matchText = (this.provider as any).webviewMatchText;
289
+ const matchText = this.provider.webviewMatchText;
272
290
  const matchFn = matchText ? (body: string) => body.includes(matchText) : undefined;
273
291
  const webviewRaw = await cdp.evaluateInWebviewFrame(webviewScript, matchFn);
274
292
  if (webviewRaw) {
@@ -281,16 +299,17 @@ export class IdeProviderInstance implements ProviderInstance {
281
299
  if (!raw) {
282
300
  const readChatScript = this.getReadChatScript();
283
301
  if (!readChatScript) return;
284
- raw = await cdp.evaluate(readChatScript, 30000) as any;
302
+ raw = await cdp.evaluate(readChatScript, 30000);
285
303
  if (typeof raw === 'string') {
286
304
  try { raw = JSON.parse(raw); } catch { return; }
287
305
  }
288
306
  }
289
307
 
290
308
  if (!raw || typeof raw !== 'object') return;
309
+ const chat = raw as ReadChatPayload;
291
310
 
292
311
  // Modal filter
293
- let { activeModal } = raw;
312
+ let { activeModal } = chat;
294
313
  if (activeModal) {
295
314
  const w = activeModal.width ?? Infinity;
296
315
  const h = activeModal.height ?? Infinity;
@@ -312,33 +331,35 @@ export class IdeProviderInstance implements ProviderInstance {
312
331
  if (pm.receivedAt) prevByHash.set(h, pm.receivedAt);
313
332
  }
314
333
  const now = Date.now();
315
- for (const msg of (raw.messages || [])) {
334
+ const messages = chat.messages || [];
335
+ for (const msg of messages) {
316
336
  const h = `${msg.role}:${(msg.content || '').slice(0, 100)}`;
317
337
  msg.receivedAt = prevByHash.get(h) || now;
318
338
  }
319
339
 
320
340
  // Filter messages by provider settings (showThinking, showToolCalls, showTerminal)
321
- if (raw.messages?.length > 0) {
341
+ if (messages.length > 0) {
322
342
  const hiddenKinds = new Set<string>();
323
343
  if (this.settings.showThinking === false) hiddenKinds.add('thought');
324
344
  if (this.settings.showToolCalls === false) hiddenKinds.add('tool');
325
345
  if (this.settings.showTerminal === false) hiddenKinds.add('terminal');
326
346
  if (hiddenKinds.size > 0) {
327
- raw.messages = raw.messages.filter((m: any) => !hiddenKinds.has(m.kind));
347
+ chat.messages = messages.filter((m) => !hiddenKinds.has(m.kind || ''));
328
348
  }
329
349
  }
330
350
 
331
- const controlValues = extractProviderControlValues(this.provider.controls, raw);
332
- if (controlValues) raw.controlValues = controlValues;
351
+ const controlValues = extractProviderControlValues(this.provider.controls, chat);
352
+ if (controlValues) chat.controlValues = controlValues;
333
353
 
334
- this.cachedChat = { ...raw, activeModal };
335
- this.detectAgentTransitions(raw, now);
354
+ this.cachedChat = { ...chat, activeModal };
355
+ this.detectAgentTransitions(chat, now);
336
356
 
337
357
  // Save history (new messageonly append)
338
358
  // Exclude last incomplete assistant message during generating status
339
- if (raw.messages?.length > 0) {
340
- let toSave = raw.messages;
341
- if (raw.status === 'generating' || raw.status === 'long_generating') {
359
+ const persistedMessages = chat.messages || messages;
360
+ if (persistedMessages.length > 0) {
361
+ let toSave = persistedMessages;
362
+ if (chat.status === 'generating' || chat.status === 'long_generating') {
342
363
  // Find and exclude last assistant message
343
364
  const lastIdx = toSave.length - 1;
344
365
  if (lastIdx >= 0 && toSave[lastIdx].role === 'assistant') {
@@ -349,7 +370,7 @@ export class IdeProviderInstance implements ProviderInstance {
349
370
  this.historyWriter.appendNewMessages(
350
371
  this.type,
351
372
  toSave,
352
- raw.title,
373
+ chat.title,
353
374
  this.instanceId,
354
375
  );
355
376
  }
@@ -368,7 +389,7 @@ export class IdeProviderInstance implements ProviderInstance {
368
389
  private getReadChatScript(): string | null {
369
390
  const scripts = this.provider.scripts;
370
391
  if (!scripts?.readChat) return null;
371
- return typeof scripts.readChat === 'function' ? scripts.readChat({}) : scripts.readChat as any;
392
+ return scripts.readChat({});
372
393
  }
373
394
 
374
395
  // ─── status transition detect ─────────────────────────────