@adhdev/daemon-core 0.8.34 → 0.8.36

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 (109) hide show
  1. package/dist/boot/daemon-lifecycle.d.ts +4 -0
  2. package/dist/commands/router.d.ts +3 -0
  3. package/dist/config/config.d.ts +5 -0
  4. package/dist/index.d.ts +2 -2
  5. package/dist/index.js +585 -256
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +584 -256
  8. package/dist/index.mjs.map +1 -1
  9. package/dist/shared-types.d.ts +286 -16
  10. package/dist/status/builders.d.ts +5 -1
  11. package/dist/status/normalize.d.ts +11 -1
  12. package/dist/status/normalize.js +36 -16
  13. package/dist/status/normalize.js.map +1 -1
  14. package/dist/status/normalize.mjs +35 -16
  15. package/dist/status/normalize.mjs.map +1 -1
  16. package/dist/status/reporter.d.ts +7 -0
  17. package/dist/status/snapshot.d.ts +5 -5
  18. package/dist/types.d.ts +1 -1
  19. package/node_modules/@adhdev/session-host-core/package.json +1 -1
  20. package/package.json +1 -1
  21. package/src/agent-stream/forward.d.ts +8 -0
  22. package/src/agent-stream/index.d.ts +6 -0
  23. package/src/agent-stream/manager.d.ts +60 -0
  24. package/src/agent-stream/poller.d.ts +41 -0
  25. package/src/agent-stream/provider-adapter.d.ts +36 -0
  26. package/src/agent-stream/types.d.ts +68 -0
  27. package/src/boot/daemon-lifecycle.d.ts +100 -0
  28. package/src/boot/daemon-lifecycle.ts +7 -0
  29. package/src/cdp/devtools.d.ts +51 -0
  30. package/src/cdp/initializer.d.ts +50 -0
  31. package/src/cdp/manager.d.ts +147 -0
  32. package/src/cdp/scanner.d.ts +58 -0
  33. package/src/cdp/setup.d.ts +58 -0
  34. package/src/cli-adapter-types.d.ts +57 -0
  35. package/src/cli-adapters/provider-cli-adapter.d.ts +177 -0
  36. package/src/cli-adapters/provider-cli-adapter.ts +115 -91
  37. package/src/cli-adapters/provider-cli-config.d.ts +30 -0
  38. package/src/cli-adapters/provider-cli-parse.d.ts +42 -0
  39. package/src/cli-adapters/provider-cli-runtime.d.ts +29 -0
  40. package/src/cli-adapters/provider-cli-shared.d.ts +158 -0
  41. package/src/cli-adapters/pty-transport.d.ts +48 -0
  42. package/src/cli-adapters/session-host-transport.d.ts +20 -0
  43. package/src/cli-adapters/spawn-env.d.ts +8 -0
  44. package/src/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +16 -0
  45. package/src/cli-adapters/terminal-backends/types.d.ts +18 -0
  46. package/src/cli-adapters/terminal-backends/xterm-backend.d.ts +17 -0
  47. package/src/cli-adapters/terminal-screen.d.ts +33 -0
  48. package/src/commands/cdp-commands.d.ts +15 -0
  49. package/src/commands/chat-commands.d.ts +15 -0
  50. package/src/commands/chat-commands.ts +192 -17
  51. package/src/commands/cli-manager.d.ts +94 -0
  52. package/src/commands/handler.d.ts +103 -0
  53. package/src/commands/router.d.ts +98 -0
  54. package/src/commands/router.ts +25 -0
  55. package/src/commands/stream-commands.d.ts +14 -0
  56. package/src/commands/stream-commands.ts +14 -10
  57. package/src/commands/upgrade-helper.d.ts +10 -0
  58. package/src/commands/workspace-commands.d.ts +11 -0
  59. package/src/config/chat-history.d.ts +99 -0
  60. package/src/config/config.d.ts +14 -0
  61. package/src/config/config.ts +8 -0
  62. package/src/config/recent-activity.d.ts +29 -0
  63. package/src/config/saved-sessions.d.ts +22 -0
  64. package/src/config/state-store.d.ts +32 -0
  65. package/src/config/workspaces.d.ts +0 -1
  66. package/src/daemon/dev-auto-implement.d.ts +43 -0
  67. package/src/daemon/dev-cdp-handlers.d.ts +22 -0
  68. package/src/daemon/dev-cli-debug.d.ts +106 -0
  69. package/src/daemon/dev-server-types.d.ts +43 -0
  70. package/src/daemon/dev-server.d.ts +140 -0
  71. package/src/daemon/scaffold-template.d.ts +32 -0
  72. package/src/daemon-core.d.ts +36 -0
  73. package/src/detection/cli-detector.d.ts +31 -0
  74. package/src/detection/ide-detector.d.ts +35 -0
  75. package/src/index.d.ts +83 -0
  76. package/src/index.ts +34 -1
  77. package/src/installer.d.ts +50 -0
  78. package/src/ipc-protocol.d.ts +111 -0
  79. package/src/launch.d.ts +46 -0
  80. package/src/logging/command-log.d.ts +31 -0
  81. package/src/logging/logger.d.ts +89 -0
  82. package/src/providers/acp-provider-instance.d.ts +102 -0
  83. package/src/providers/approval-utils.d.ts +7 -0
  84. package/src/providers/cli-provider-instance.d.ts +86 -0
  85. package/src/providers/contracts.d.ts +193 -1
  86. package/src/providers/control-effects.d.ts +4 -0
  87. package/src/providers/extension-provider-instance.d.ts +61 -0
  88. package/src/providers/ide-provider-instance.d.ts +70 -0
  89. package/src/providers/provider-instance-manager.d.ts +84 -0
  90. package/src/providers/provider-instance.d.ts +7 -1
  91. package/src/providers/provider-loader.d.ts +299 -0
  92. package/src/providers/status-monitor.d.ts +48 -0
  93. package/src/providers/version-archive.d.ts +52 -0
  94. package/src/session-host/runtime-support.d.ts +8 -0
  95. package/src/sessions/reconcile.d.ts +22 -0
  96. package/src/sessions/registry.d.ts +24 -0
  97. package/src/shared-types-extra.d.ts +29 -0
  98. package/src/shared-types.d.ts +204 -38
  99. package/src/shared-types.ts +319 -16
  100. package/src/status/builders.d.ts +33 -0
  101. package/src/status/builders.ts +110 -54
  102. package/src/status/normalize.ts +54 -19
  103. package/src/status/reporter.d.ts +69 -0
  104. package/src/status/reporter.ts +104 -26
  105. package/src/status/snapshot.d.ts +58 -0
  106. package/src/status/snapshot.ts +79 -41
  107. package/src/system/host-memory.d.ts +19 -0
  108. package/src/types.d.ts +3 -7
  109. package/src/types.ts +1 -1
@@ -0,0 +1,33 @@
1
+ /**
2
+ * PTY screen snapshot abstraction.
3
+ *
4
+ * Terminal viewport backend selection.
5
+ *
6
+ * Runtime preference is backend-agnostic:
7
+ * - prefer ghostty-vt when available (or when explicitly requested)
8
+ * - fall back to xterm when ghostty-vt is unavailable
9
+ */
10
+ import type { TerminalViewportBackendKind, TerminalViewportBackendPreference } from './terminal-backends/types.js';
11
+ export declare function getTerminalBackendRuntimeStatus(): {
12
+ backend: TerminalViewportBackendKind;
13
+ preference: TerminalViewportBackendPreference;
14
+ ghosttyAvailable: boolean;
15
+ };
16
+ export declare class TerminalScreen {
17
+ readonly backendKind: TerminalViewportBackendKind;
18
+ private rows;
19
+ private cols;
20
+ private readonly preference;
21
+ private terminal;
22
+ constructor(rows?: number, cols?: number);
23
+ reset(rows?: number, cols?: number): void;
24
+ resize(rows: number, cols: number): void;
25
+ write(data: string): void;
26
+ getText(): string;
27
+ getCursorPosition(): {
28
+ col: number;
29
+ row: number;
30
+ };
31
+ dispose(): void;
32
+ private createBackend;
33
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * CDP Commands — cdpEval, screenshot, cdpCommand, cdpBatch, cdpRemoteAction,
3
+ * discoverAgents, file operations
4
+ */
5
+ import type { CommandResult, CommandHelpers } from './handler.js';
6
+ export declare function handleCdpEval(h: CommandHelpers, args: any): Promise<CommandResult>;
7
+ export declare function handleScreenshot(h: CommandHelpers, args: any): Promise<CommandResult>;
8
+ export declare function handleCdpCommand(h: CommandHelpers, args: any): Promise<CommandResult>;
9
+ export declare function handleCdpBatch(h: CommandHelpers, args: any): Promise<CommandResult>;
10
+ export declare function handleCdpRemoteAction(h: CommandHelpers, args: any): Promise<CommandResult>;
11
+ export declare function handleDiscoverAgents(h: CommandHelpers, args: any): Promise<CommandResult>;
12
+ export declare function handleFileRead(h: CommandHelpers, args: any): Promise<CommandResult>;
13
+ export declare function handleFileWrite(h: CommandHelpers, args: any): Promise<CommandResult>;
14
+ export declare function handleFileList(h: CommandHelpers, args: any): Promise<CommandResult>;
15
+ export declare function handleFileListBrowse(h: CommandHelpers, args: any): Promise<CommandResult>;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Chat Commands — readChat, sendChat, listChats, newChat, switchChat,
3
+ * setMode, changeModel, setThoughtLevel, resolveAction, chatHistory
4
+ */
5
+ import type { CommandResult, CommandHelpers } from './handler.js';
6
+ export declare function handleChatHistory(h: CommandHelpers, args: any): Promise<CommandResult>;
7
+ export declare function handleReadChat(h: CommandHelpers, args: any): Promise<CommandResult>;
8
+ export declare function handleSendChat(h: CommandHelpers, args: any): Promise<CommandResult>;
9
+ export declare function handleListChats(h: CommandHelpers, args: any): Promise<CommandResult>;
10
+ export declare function handleNewChat(h: CommandHelpers, args: any): Promise<CommandResult>;
11
+ export declare function handleSwitchChat(h: CommandHelpers, args: any): Promise<CommandResult>;
12
+ export declare function handleSetMode(h: CommandHelpers, args: any): Promise<CommandResult>;
13
+ export declare function handleChangeModel(h: CommandHelpers, args: any): Promise<CommandResult>;
14
+ export declare function handleSetThoughtLevel(h: CommandHelpers, args: any): Promise<CommandResult>;
15
+ export declare function handleResolveAction(h: CommandHelpers, args: any): Promise<CommandResult>;
@@ -5,15 +5,30 @@
5
5
 
6
6
  import type { CommandResult, CommandHelpers } from './handler.js';
7
7
  import type { CliAdapter } from '../cli-adapter-types.js';
8
- import type { ProviderModule, ProviderScripts } from '../providers/contracts.js';
8
+ import { flattenContent, type ProviderModule, type ProviderScripts } from '../providers/contracts.js';
9
9
  import type { ProviderInstance } from '../providers/provider-instance.js';
10
10
  import { readChatHistory } from '../config/chat-history.js';
11
11
  import { LOG } from '../logging/logger.js';
12
- import type { SessionTransport } from '../shared-types.js';
12
+ import type { ChatMessage } from '../types.js';
13
+ import type { ReadChatCursor, ReadChatSyncMode, SessionTransport } from '../shared-types.js';
13
14
 
14
15
  const RECENT_SEND_WINDOW_MS = 1200;
15
16
  const recentSendByTarget = new Map<string, number>();
16
17
 
18
+ function hashSignatureParts(parts: string[]): string {
19
+ let hash = 0x811c9dc5;
20
+ for (const part of parts) {
21
+ const text = String(part || '');
22
+ for (let i = 0; i < text.length; i += 1) {
23
+ hash ^= text.charCodeAt(i);
24
+ hash = Math.imul(hash, 0x01000193) >>> 0;
25
+ }
26
+ hash ^= 0xff;
27
+ hash = Math.imul(hash, 0x01000193) >>> 0;
28
+ }
29
+ return hash.toString(16).padStart(8, '0');
30
+ }
31
+
17
32
  interface ApprovalSelectableInstance extends ProviderInstance {
18
33
  recordApprovalSelection?(buttonText: string): void;
19
34
  }
@@ -113,6 +128,163 @@ function parseMaybeJson(value: any): any {
113
128
  }
114
129
  }
115
130
 
131
+ function getChatMessageSignature(message: ChatMessage | null | undefined): string {
132
+ if (!message) return '';
133
+ let content = '';
134
+ try {
135
+ content = JSON.stringify(message.content ?? '');
136
+ } catch {
137
+ content = String(message.content ?? '');
138
+ }
139
+ return hashSignatureParts([
140
+ String(message.id || ''),
141
+ String(message.index ?? ''),
142
+ String(message.role || ''),
143
+ String(message.receivedAt ?? message.timestamp ?? ''),
144
+ content,
145
+ ]);
146
+ }
147
+
148
+ function normalizeReadChatCursor(args: any): Required<ReadChatCursor> {
149
+ const knownMessageCount = Math.max(0, Number(args?.knownMessageCount || 0));
150
+ const lastMessageSignature = typeof args?.lastMessageSignature === 'string'
151
+ ? args.lastMessageSignature
152
+ : '';
153
+ const tailLimit = Math.max(0, Number(args?.tailLimit || 0));
154
+ return { knownMessageCount, lastMessageSignature, tailLimit };
155
+ }
156
+
157
+ function normalizeReadChatMessages(payload: Record<string, any>): ChatMessage[] {
158
+ const messages = Array.isArray(payload.messages) ? payload.messages as ChatMessage[] : [];
159
+ return messages;
160
+ }
161
+
162
+ function deriveHistoryDedupKey(message: ChatMessage & { _unitKey?: string; _turnKey?: string }): string | undefined {
163
+ const unitKey = typeof message._unitKey === 'string' ? message._unitKey.trim() : '';
164
+ if (unitKey) return `read_chat:${unitKey}`;
165
+
166
+ const turnKey = typeof message._turnKey === 'string' ? message._turnKey.trim() : '';
167
+ if (!turnKey) return undefined;
168
+
169
+ let content = '';
170
+ try {
171
+ content = JSON.stringify(message.content ?? '');
172
+ } catch {
173
+ content = String(message.content ?? '');
174
+ }
175
+ return `read_chat:${turnKey}:${String(message.role || '').toLowerCase()}:${content}`;
176
+ }
177
+
178
+ function toHistoryPersistedMessages(messages: ChatMessage[]): Array<{
179
+ role: string;
180
+ content: string;
181
+ receivedAt?: number;
182
+ kind?: string;
183
+ senderName?: string;
184
+ historyDedupKey?: string;
185
+ }> {
186
+ return messages.map((message) => ({
187
+ role: message.role,
188
+ content: flattenContent(message.content),
189
+ receivedAt: typeof message.receivedAt === 'number' ? message.receivedAt : undefined,
190
+ kind: typeof message.kind === 'string' ? message.kind : undefined,
191
+ senderName: typeof message.senderName === 'string' ? message.senderName : undefined,
192
+ historyDedupKey: deriveHistoryDedupKey(message as ChatMessage & { _unitKey?: string; _turnKey?: string }),
193
+ }));
194
+ }
195
+
196
+ function computeReadChatSync(messages: ChatMessage[], cursor: Required<ReadChatCursor>): {
197
+ syncMode: ReadChatSyncMode;
198
+ replaceFrom: number;
199
+ messages: ChatMessage[];
200
+ totalMessages: number;
201
+ lastMessageSignature: string;
202
+ } {
203
+ const totalMessages = messages.length;
204
+ const lastMessageSignature = getChatMessageSignature(messages[totalMessages - 1]);
205
+ const { knownMessageCount, lastMessageSignature: knownSignature } = cursor;
206
+
207
+ if (!knownMessageCount || !knownSignature) {
208
+ return {
209
+ syncMode: 'full',
210
+ replaceFrom: 0,
211
+ messages,
212
+ totalMessages,
213
+ lastMessageSignature,
214
+ };
215
+ }
216
+
217
+ if (knownMessageCount > totalMessages) {
218
+ return {
219
+ syncMode: 'full',
220
+ replaceFrom: 0,
221
+ messages,
222
+ totalMessages,
223
+ lastMessageSignature,
224
+ };
225
+ }
226
+
227
+ if (knownMessageCount === totalMessages && knownSignature === lastMessageSignature) {
228
+ return {
229
+ syncMode: 'noop',
230
+ replaceFrom: totalMessages,
231
+ messages: [],
232
+ totalMessages,
233
+ lastMessageSignature,
234
+ };
235
+ }
236
+
237
+ if (knownMessageCount < totalMessages) {
238
+ const anchorSignature = getChatMessageSignature(messages[knownMessageCount - 1]);
239
+ if (anchorSignature === knownSignature) {
240
+ return {
241
+ syncMode: 'append',
242
+ replaceFrom: knownMessageCount,
243
+ messages: messages.slice(knownMessageCount),
244
+ totalMessages,
245
+ lastMessageSignature,
246
+ };
247
+ }
248
+ }
249
+
250
+ const replaceFrom = Math.max(0, Math.min(knownMessageCount - 1, totalMessages));
251
+ return {
252
+ syncMode: replaceFrom === 0 ? 'full' : 'replace_tail',
253
+ replaceFrom,
254
+ messages: replaceFrom === 0 ? messages : messages.slice(replaceFrom),
255
+ totalMessages,
256
+ lastMessageSignature,
257
+ };
258
+ }
259
+
260
+ function buildReadChatCommandResult(payload: Record<string, any>, args: any): CommandResult {
261
+ const messages = normalizeReadChatMessages(payload);
262
+ const cursor = normalizeReadChatCursor(args);
263
+ if (!cursor.knownMessageCount && !cursor.lastMessageSignature && cursor.tailLimit > 0 && messages.length > cursor.tailLimit) {
264
+ const tailMessages = messages.slice(-cursor.tailLimit);
265
+ const lastMessageSignature = getChatMessageSignature(tailMessages[tailMessages.length - 1]);
266
+ return {
267
+ success: true,
268
+ ...payload,
269
+ messages: tailMessages,
270
+ syncMode: 'full',
271
+ replaceFrom: 0,
272
+ totalMessages: messages.length,
273
+ lastMessageSignature,
274
+ };
275
+ }
276
+ const sync = computeReadChatSync(messages, cursor);
277
+ return {
278
+ success: true,
279
+ ...payload,
280
+ messages: sync.messages,
281
+ syncMode: sync.syncMode,
282
+ replaceFrom: sync.replaceFrom,
283
+ totalMessages: sync.totalMessages,
284
+ lastMessageSignature: sync.lastMessageSignature,
285
+ };
286
+ }
287
+
116
288
  function didProviderConfirmSend(result: any): boolean {
117
289
  const parsed = parseMaybeJson(result);
118
290
  if (parsed === true) return true;
@@ -201,12 +373,11 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
201
373
  _log(`${transport} adapter: ${adapter.cliType}`);
202
374
  const status = adapter.getStatus();
203
375
  if (status) {
204
- return {
205
- success: true,
376
+ return buildReadChatCommandResult({
206
377
  messages: status.messages || [],
207
378
  status: status.status,
208
379
  activeModal: status.activeModal,
209
- };
380
+ }, args);
210
381
  }
211
382
  }
212
383
  return { success: false, error: `${transport} adapter not found` };
@@ -223,12 +394,12 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
223
394
  _log(`Extension OK: ${parsed.messages?.length || 0} msgs`);
224
395
  h.historyWriter.appendNewMessages(
225
396
  provider?.type || 'unknown_extension',
226
- parsed.messages || [],
397
+ toHistoryPersistedMessages(normalizeReadChatMessages(parsed)),
227
398
  parsed.title,
228
399
  args?.targetSessionId,
229
400
  historySessionId,
230
401
  );
231
- return { success: true, ...parsed };
402
+ return buildReadChatCommandResult(parsed, args);
232
403
  }
233
404
  }
234
405
  } catch (e: any) {
@@ -241,21 +412,25 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
241
412
  if (cdp && parentSessionId) {
242
413
  const stream = await h.agentStream.collectActiveSession(cdp, parentSessionId);
243
414
  if (stream?.agentType !== provider?.type) {
244
- return { success: true, messages: [], status: 'idle' };
415
+ return buildReadChatCommandResult({ messages: [], status: 'idle' }, args);
245
416
  }
246
417
  if (stream) {
247
418
  h.historyWriter.appendNewMessages(
248
419
  stream.agentType,
249
- stream.messages || [],
420
+ toHistoryPersistedMessages(stream.messages || []),
250
421
  undefined,
251
422
  args?.targetSessionId,
252
423
  historySessionId,
253
424
  );
254
- return { success: true, messages: stream.messages || [], status: stream.status, agentType: stream.agentType };
425
+ return buildReadChatCommandResult({
426
+ messages: stream.messages || [],
427
+ status: stream.status,
428
+ agentType: stream.agentType,
429
+ }, args);
255
430
  }
256
431
  }
257
432
  }
258
- return { success: true, messages: [], status: 'idle' };
433
+ return buildReadChatCommandResult({ messages: [], status: 'idle' }, args);
259
434
  }
260
435
 
261
436
  // IDE category (default): cdp.evaluate
@@ -278,18 +453,18 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
278
453
  _log(`Webview OK: ${parsed.messages?.length || 0} msgs`);
279
454
  h.historyWriter.appendNewMessages(
280
455
  provider?.type || getCurrentProviderType(h, 'unknown_webview'),
281
- parsed.messages || [],
456
+ toHistoryPersistedMessages(normalizeReadChatMessages(parsed)),
282
457
  parsed.title,
283
458
  args?.targetSessionId,
284
459
  historySessionId,
285
460
  );
286
- return { success: true, ...parsed };
461
+ return buildReadChatCommandResult(parsed, args);
287
462
  }
288
463
  }
289
464
  } catch (e: any) {
290
465
  _log(`Webview readChat error: ${e.message}`);
291
466
  }
292
- return { success: true, messages: [], status: 'idle' };
467
+ return buildReadChatCommandResult({ messages: [], status: 'idle' }, args);
293
468
  }
294
469
 
295
470
  // Regular IDE (Cursor, Windsurf, Trae etc) → main DOM evaluate
@@ -303,19 +478,19 @@ export async function handleReadChat(h: CommandHelpers, args: any): Promise<Comm
303
478
  _log(`OK: ${parsed.messages?.length} msgs`);
304
479
  h.historyWriter.appendNewMessages(
305
480
  provider?.type || getCurrentProviderType(h, 'unknown_ide'),
306
- parsed.messages || [],
481
+ toHistoryPersistedMessages(normalizeReadChatMessages(parsed)),
307
482
  parsed.title,
308
483
  args?.targetSessionId,
309
484
  historySessionId,
310
485
  );
311
- return { success: true, ...parsed };
486
+ return buildReadChatCommandResult(parsed, args);
312
487
  }
313
488
  } catch (e: any) {
314
489
  LOG.info('Command', `[read_chat] Script error: ${e.message}`);
315
490
  }
316
491
  }
317
492
 
318
- return { success: true, messages: [], status: 'idle' };
493
+ return buildReadChatCommandResult({ messages: [], status: 'idle' }, args);
319
494
  }
320
495
 
321
496
  export async function handleSendChat(h: CommandHelpers, args: any): Promise<CommandResult> {
@@ -0,0 +1,94 @@
1
+ /**
2
+ * DaemonCliManager — CLI session creation, management, and command handling
3
+ *
4
+ * Separated from adhdev-daemon.ts.
5
+ * CLI cases of createAdapter, startCliSession, stopCliSession, executeDaemonCommand extracted to independent module extract.
6
+ */
7
+ import type { ProviderInstanceManager } from '../providers/provider-instance-manager.js';
8
+ import { ProviderLoader } from '../providers/provider-loader.js';
9
+ import type { ProviderResumeCapability } from '../providers/contracts.js';
10
+ import type { CliAdapter } from '../cli-adapter-types.js';
11
+ import type { PtyTransportFactory } from '../cli-adapters/pty-transport.js';
12
+ import type { SessionRegistry } from '../sessions/registry.js';
13
+ export interface CliManagerDeps {
14
+ /** Server connection — injected into adapter */
15
+ getServerConn(): any | null;
16
+ /** P2P — PTY output transmit */
17
+ getP2p(): {
18
+ broadcastSessionOutput(key: string, data: string): void;
19
+ } | null;
20
+ /** StatusReporter callback */
21
+ onStatusChange(): void;
22
+ removeAgentTracking(key: string): void;
23
+ /** InstanceManager — register in CLI unified status */
24
+ getInstanceManager(): ProviderInstanceManager | null;
25
+ getSessionRegistry?(): SessionRegistry | null;
26
+ createPtyTransportFactory?: (params: CliTransportFactoryParams) => PtyTransportFactory | null;
27
+ listHostedCliRuntimes?: () => Promise<HostedCliRuntimeDescriptor[]>;
28
+ }
29
+ type CommandResult = {
30
+ success: boolean;
31
+ [key: string]: unknown;
32
+ };
33
+ export interface CliTransportFactoryParams {
34
+ runtimeId: string;
35
+ providerType: string;
36
+ workspace: string;
37
+ cliArgs?: string[];
38
+ providerSessionId?: string;
39
+ attachExisting?: boolean;
40
+ }
41
+ export interface HostedCliRuntimeDescriptor {
42
+ runtimeId: string;
43
+ runtimeKey?: string;
44
+ displayName?: string;
45
+ workspaceLabel?: string;
46
+ lifecycle?: 'starting' | 'running' | 'stopping' | 'stopped' | 'failed' | 'interrupted';
47
+ recoveryState?: string | null;
48
+ cliType: string;
49
+ workspace: string;
50
+ cliArgs?: string[];
51
+ providerSessionId?: string;
52
+ }
53
+ export declare function supportsExplicitSessionResume(resume?: ProviderResumeCapability): boolean;
54
+ export declare class DaemonCliManager {
55
+ readonly adapters: Map<string, CliAdapter>;
56
+ private deps;
57
+ private providerLoader;
58
+ constructor(deps: CliManagerDeps, providerLoader: ProviderLoader);
59
+ getCliKey(cliType: string, dir: string): string;
60
+ getSessionPresentationMode(sessionId: string): 'terminal' | 'chat' | null;
61
+ isTerminalSession(sessionId: string): boolean;
62
+ private persistRecentActivity;
63
+ private getTransportFactory;
64
+ private createAdapter;
65
+ private startCliExitMonitor;
66
+ private registerCliInstance;
67
+ startSession(cliType: string, workingDir: string, cliArgs?: string[], initialModel?: string, options?: {
68
+ resumeSessionId?: string;
69
+ }): Promise<{
70
+ runtimeSessionId: string;
71
+ providerSessionId?: string;
72
+ }>;
73
+ stopSession(key: string): Promise<void>;
74
+ stopSessionWithMode(key: string, mode: 'hard' | 'save'): Promise<void>;
75
+ shutdownAll(): void;
76
+ detachAll(): void;
77
+ restoreHostedSessions(records?: HostedCliRuntimeDescriptor[]): Promise<number>;
78
+ /**
79
+ * Search for CLI adapter. Priority order:
80
+ * 0. sessionId (UUID direct match)
81
+ * 1. agentType + dir (iteration match)
82
+ * 2. agentType fuzzy match (⚠ returns first match when multiple sessions exist)
83
+ */
84
+ findAdapter(agentType: string, opts?: {
85
+ dir?: string;
86
+ instanceKey?: string;
87
+ }): {
88
+ adapter: CliAdapter;
89
+ key: string;
90
+ } | null;
91
+ private findAdapterBySessionId;
92
+ handleCliCommand(cmd: string, args: any): Promise<CommandResult | null>;
93
+ }
94
+ export {};
@@ -0,0 +1,103 @@
1
+ /**
2
+ * DaemonCommandHandler — unified command routing for CDP & CLI
3
+ *
4
+ * Routes incoming commands (from server WS, P2P, or local WS) to
5
+ * the correct CDP manager or CLI adapter.
6
+ *
7
+ * Key concepts:
8
+ * - extractIdeType(): determines target IDE from targetSessionId or ideType
9
+ * - getCdp(): returns the DaemonCdpManager for current command
10
+ * - getProvider(): returns the ProviderModule for current command
11
+ * - handle(): main entry point, sets context then dispatches
12
+ */
13
+ import type { DaemonCdpManager } from '../cdp/manager.js';
14
+ import { ProviderLoader } from '../providers/provider-loader.js';
15
+ import type { ProviderInstanceManager } from '../providers/provider-instance-manager.js';
16
+ import type { ProviderModule } from '../providers/contracts.js';
17
+ import type { DaemonAgentStreamManager } from '../agent-stream/index.js';
18
+ import type { CliAdapter } from '../cli-adapter-types.js';
19
+ import { ChatHistoryWriter } from '../config/chat-history.js';
20
+ import type { SessionRegistry, SessionRuntimeTarget } from '../sessions/registry.js';
21
+ export interface CommandResult {
22
+ success: boolean;
23
+ [key: string]: unknown;
24
+ }
25
+ export interface CommandContext {
26
+ cdpManagers: Map<string, DaemonCdpManager>;
27
+ ideType: string;
28
+ adapters: Map<string, CliAdapter>;
29
+ providerLoader?: ProviderLoader;
30
+ /** ProviderInstanceManager — for runtime settings propagation */
31
+ instanceManager?: ProviderInstanceManager;
32
+ sessionRegistry?: SessionRegistry;
33
+ onProviderSettingChanged?: (providerType: string, key: string, value: any) => Promise<void> | void;
34
+ }
35
+ /**
36
+ * Shared helpers interface — passed to sub-module command functions
37
+ * for accessing CDP, providers, agent streams, and other handler-owned state.
38
+ */
39
+ export interface CommandHelpers {
40
+ getCdp(ideType?: string): DaemonCdpManager | null;
41
+ getProvider(overrideType?: string): ProviderModule | undefined;
42
+ getProviderScript(scriptName: string, params?: Record<string, string>, ideType?: string): string | null;
43
+ evaluateProviderScript(scriptName: string, params?: Record<string, string>, timeout?: number): Promise<{
44
+ result: any;
45
+ category: string;
46
+ } | null>;
47
+ getCliAdapter(type?: string): CliAdapter | null;
48
+ readonly currentManagerKey: string | undefined;
49
+ readonly currentIdeType: string | undefined;
50
+ readonly currentProviderType: string | undefined;
51
+ readonly currentSession: SessionRuntimeTarget | undefined;
52
+ readonly agentStream: DaemonAgentStreamManager | null;
53
+ readonly ctx: CommandContext;
54
+ readonly historyWriter: ChatHistoryWriter;
55
+ }
56
+ export declare class DaemonCommandHandler implements CommandHelpers {
57
+ private _ctx;
58
+ private _agentStream;
59
+ private domHandlers;
60
+ private _historyWriter;
61
+ /** Current request route context */
62
+ private _currentRoute;
63
+ constructor(ctx: CommandContext);
64
+ get ctx(): CommandContext;
65
+ get agentStream(): DaemonAgentStreamManager | null;
66
+ get historyWriter(): ChatHistoryWriter;
67
+ get currentManagerKey(): string | undefined;
68
+ get currentIdeType(): string | undefined;
69
+ get currentProviderType(): string | undefined;
70
+ get currentSession(): SessionRuntimeTarget | undefined;
71
+ /** Get CDP manager for a specific session or manager key. */
72
+ getCdp(ideType?: string): DaemonCdpManager | null;
73
+ /**
74
+ * Get provider module — _currentProviderType (agentType priority) use.
75
+ */
76
+ getProvider(overrideType?: string): ProviderModule | undefined;
77
+ /** Get a provider script by name from ProviderLoader. */
78
+ getProviderScript(scriptName: string, params?: Record<string, string>, ideType?: string): string | null;
79
+ /**
80
+ * per-category CDP script execute:
81
+ * IDE → cdp.evaluate(script) (main window)
82
+ * Extension → cdp.evaluateInSession(sessionId, script) (webview)
83
+ */
84
+ evaluateProviderScript(scriptName: string, params?: Record<string, string>, timeout?: number): Promise<{
85
+ result: any;
86
+ category: string;
87
+ } | null>;
88
+ /** CLI adapter search */
89
+ getCliAdapter(type?: string): CliAdapter | null;
90
+ private inferProviderType;
91
+ private resolveRoute;
92
+ /** Extract CDP scope key from target session or explicit ideType */
93
+ private extractIdeType;
94
+ private logCommandStart;
95
+ private logCommandEnd;
96
+ setAgentStreamManager(manager: DaemonAgentStreamManager): void;
97
+ handle(cmd: string, args: any): Promise<CommandResult>;
98
+ private dispatch;
99
+ private handleRefreshScripts;
100
+ private proxyDevServerPost;
101
+ private proxyDevServerGet;
102
+ private proxyDevServerScaffold;
103
+ }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * DaemonCommandRouter — Unified command routing for daemon-level commands
3
+ *
4
+ * Unified command routing for daemon-level commands.
5
+ *
6
+ * Routing flow:
7
+ * 1. Daemon-level commands (launch_ide, stop_ide, restart_ide, etc.) → handled here
8
+ * 2. CLI/ACP commands → delegated to cliManager
9
+ * 3. Everything else → delegated to commandHandler.handle()
10
+ */
11
+ import { DaemonCdpManager } from '../cdp/manager.js';
12
+ import { DaemonCommandHandler } from './handler.js';
13
+ import { DaemonCliManager } from './cli-manager.js';
14
+ import type { ProviderLoader } from '../providers/provider-loader.js';
15
+ import type { ProviderInstanceManager } from '../providers/provider-instance-manager.js';
16
+ import { SessionRegistry } from '../sessions/registry.js';
17
+ export interface SessionHostControlPlane {
18
+ getDiagnostics(payload?: {
19
+ includeSessions?: boolean;
20
+ limit?: number;
21
+ }): Promise<any>;
22
+ listSessions(): Promise<any[]>;
23
+ stopSession(sessionId: string): Promise<any>;
24
+ resumeSession(sessionId: string): Promise<any>;
25
+ restartSession(sessionId: string): Promise<any>;
26
+ sendSignal(sessionId: string, signal: string): Promise<any>;
27
+ forceDetachClient(sessionId: string, clientId: string): Promise<any>;
28
+ pruneDuplicateSessions(payload?: {
29
+ providerType?: string;
30
+ workspace?: string;
31
+ dryRun?: boolean;
32
+ }): Promise<any>;
33
+ acquireWrite(payload: {
34
+ sessionId: string;
35
+ clientId: string;
36
+ ownerType: 'agent' | 'user';
37
+ force?: boolean;
38
+ }): Promise<any>;
39
+ releaseWrite(payload: {
40
+ sessionId: string;
41
+ clientId: string;
42
+ }): Promise<any>;
43
+ }
44
+ export interface CommandRouterDeps {
45
+ commandHandler: DaemonCommandHandler;
46
+ cliManager: DaemonCliManager;
47
+ cdpManagers: Map<string, DaemonCdpManager>;
48
+ providerLoader: ProviderLoader;
49
+ instanceManager: ProviderInstanceManager;
50
+ /** Reference to detected IDEs array (mutable — router updates it) */
51
+ detectedIdes: {
52
+ value: any[];
53
+ };
54
+ sessionRegistry: SessionRegistry;
55
+ /** Callback for CDP manager creation after launch_ide */
56
+ onCdpManagerCreated?: (ideType: string, manager: DaemonCdpManager) => void;
57
+ /** Callback after IDE connected (e.g., startAgentStreamPolling) */
58
+ onIdeConnected?: () => void;
59
+ /** Callback after status change (stop_ide, restart) */
60
+ onStatusChange?: () => void;
61
+ /** Callback after chat-related commands */
62
+ onPostChatCommand?: () => void;
63
+ /** Get a connected CDP manager (for agent stream reset check) */
64
+ getCdpLogFn?: (ideType: string) => (msg: string) => void;
65
+ /** Package name for upgrade detection ('adhdev' or '@adhdev/daemon-standalone') */
66
+ packageName?: string;
67
+ /** Session host control plane */
68
+ sessionHostControl?: SessionHostControlPlane | null;
69
+ }
70
+ export interface CommandRouterResult {
71
+ success: boolean;
72
+ [key: string]: unknown;
73
+ }
74
+ export declare class DaemonCommandRouter {
75
+ private deps;
76
+ constructor(deps: CommandRouterDeps);
77
+ /**
78
+ * Unified command routing.
79
+ * Returns result for all commands:
80
+ * 1. Daemon-level commands (launch_ide, stop_ide, etc.)
81
+ * 2. CLI commands (launch_cli, stop_cli, agent_command)
82
+ * 3. DaemonCommandHandler delegation (CDP/agent-stream/file commands)
83
+ *
84
+ * @param cmd Command name
85
+ * @param args Command arguments
86
+ * @param source Log source ('ws' | 'p2p' | 'standalone' | etc.)
87
+ */
88
+ execute(cmd: string, args: any, source?: string): Promise<CommandRouterResult>;
89
+ /**
90
+ * Daemon-level command execution (IDE start/stop/restart, CLI, detect, logs).
91
+ * Returns null if not handled at this level → caller delegates to CommandHandler.
92
+ */
93
+ private executeDaemonCommand;
94
+ /**
95
+ * IDE stop: CDP disconnect + InstanceManager cleanup + optionally kill OS process
96
+ */
97
+ private stopIde;
98
+ }