@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.
- package/dist/boot/daemon-lifecycle.d.ts +4 -0
- package/dist/commands/router.d.ts +3 -0
- package/dist/config/config.d.ts +5 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +585 -256
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +584 -256
- package/dist/index.mjs.map +1 -1
- package/dist/shared-types.d.ts +286 -16
- package/dist/status/builders.d.ts +5 -1
- package/dist/status/normalize.d.ts +11 -1
- package/dist/status/normalize.js +36 -16
- package/dist/status/normalize.js.map +1 -1
- package/dist/status/normalize.mjs +35 -16
- package/dist/status/normalize.mjs.map +1 -1
- package/dist/status/reporter.d.ts +7 -0
- package/dist/status/snapshot.d.ts +5 -5
- package/dist/types.d.ts +1 -1
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/agent-stream/forward.d.ts +8 -0
- package/src/agent-stream/index.d.ts +6 -0
- package/src/agent-stream/manager.d.ts +60 -0
- package/src/agent-stream/poller.d.ts +41 -0
- package/src/agent-stream/provider-adapter.d.ts +36 -0
- package/src/agent-stream/types.d.ts +68 -0
- package/src/boot/daemon-lifecycle.d.ts +100 -0
- package/src/boot/daemon-lifecycle.ts +7 -0
- package/src/cdp/devtools.d.ts +51 -0
- package/src/cdp/initializer.d.ts +50 -0
- package/src/cdp/manager.d.ts +147 -0
- package/src/cdp/scanner.d.ts +58 -0
- package/src/cdp/setup.d.ts +58 -0
- package/src/cli-adapter-types.d.ts +57 -0
- package/src/cli-adapters/provider-cli-adapter.d.ts +177 -0
- package/src/cli-adapters/provider-cli-adapter.ts +115 -91
- package/src/cli-adapters/provider-cli-config.d.ts +30 -0
- package/src/cli-adapters/provider-cli-parse.d.ts +42 -0
- package/src/cli-adapters/provider-cli-runtime.d.ts +29 -0
- package/src/cli-adapters/provider-cli-shared.d.ts +158 -0
- package/src/cli-adapters/pty-transport.d.ts +48 -0
- package/src/cli-adapters/session-host-transport.d.ts +20 -0
- package/src/cli-adapters/spawn-env.d.ts +8 -0
- package/src/cli-adapters/terminal-backends/ghostty-vt-backend.d.ts +16 -0
- package/src/cli-adapters/terminal-backends/types.d.ts +18 -0
- package/src/cli-adapters/terminal-backends/xterm-backend.d.ts +17 -0
- package/src/cli-adapters/terminal-screen.d.ts +33 -0
- package/src/commands/cdp-commands.d.ts +15 -0
- package/src/commands/chat-commands.d.ts +15 -0
- package/src/commands/chat-commands.ts +192 -17
- package/src/commands/cli-manager.d.ts +94 -0
- package/src/commands/handler.d.ts +103 -0
- package/src/commands/router.d.ts +98 -0
- package/src/commands/router.ts +25 -0
- package/src/commands/stream-commands.d.ts +14 -0
- package/src/commands/stream-commands.ts +14 -10
- package/src/commands/upgrade-helper.d.ts +10 -0
- package/src/commands/workspace-commands.d.ts +11 -0
- package/src/config/chat-history.d.ts +99 -0
- package/src/config/config.d.ts +14 -0
- package/src/config/config.ts +8 -0
- package/src/config/recent-activity.d.ts +29 -0
- package/src/config/saved-sessions.d.ts +22 -0
- package/src/config/state-store.d.ts +32 -0
- package/src/config/workspaces.d.ts +0 -1
- package/src/daemon/dev-auto-implement.d.ts +43 -0
- package/src/daemon/dev-cdp-handlers.d.ts +22 -0
- package/src/daemon/dev-cli-debug.d.ts +106 -0
- package/src/daemon/dev-server-types.d.ts +43 -0
- package/src/daemon/dev-server.d.ts +140 -0
- package/src/daemon/scaffold-template.d.ts +32 -0
- package/src/daemon-core.d.ts +36 -0
- package/src/detection/cli-detector.d.ts +31 -0
- package/src/detection/ide-detector.d.ts +35 -0
- package/src/index.d.ts +83 -0
- package/src/index.ts +34 -1
- package/src/installer.d.ts +50 -0
- package/src/ipc-protocol.d.ts +111 -0
- package/src/launch.d.ts +46 -0
- package/src/logging/command-log.d.ts +31 -0
- package/src/logging/logger.d.ts +89 -0
- package/src/providers/acp-provider-instance.d.ts +102 -0
- package/src/providers/approval-utils.d.ts +7 -0
- package/src/providers/cli-provider-instance.d.ts +86 -0
- package/src/providers/contracts.d.ts +193 -1
- package/src/providers/control-effects.d.ts +4 -0
- package/src/providers/extension-provider-instance.d.ts +61 -0
- package/src/providers/ide-provider-instance.d.ts +70 -0
- package/src/providers/provider-instance-manager.d.ts +84 -0
- package/src/providers/provider-instance.d.ts +7 -1
- package/src/providers/provider-loader.d.ts +299 -0
- package/src/providers/status-monitor.d.ts +48 -0
- package/src/providers/version-archive.d.ts +52 -0
- package/src/session-host/runtime-support.d.ts +8 -0
- package/src/sessions/reconcile.d.ts +22 -0
- package/src/sessions/registry.d.ts +24 -0
- package/src/shared-types-extra.d.ts +29 -0
- package/src/shared-types.d.ts +204 -38
- package/src/shared-types.ts +319 -16
- package/src/status/builders.d.ts +33 -0
- package/src/status/builders.ts +110 -54
- package/src/status/normalize.ts +54 -19
- package/src/status/reporter.d.ts +69 -0
- package/src/status/reporter.ts +104 -26
- package/src/status/snapshot.d.ts +58 -0
- package/src/status/snapshot.ts +79 -41
- package/src/system/host-memory.d.ts +19 -0
- package/src/types.d.ts +3 -7
- 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
|
|
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 {
|
|
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
|
|
397
|
+
toHistoryPersistedMessages(normalizeReadChatMessages(parsed)),
|
|
227
398
|
parsed.title,
|
|
228
399
|
args?.targetSessionId,
|
|
229
400
|
historySessionId,
|
|
230
401
|
);
|
|
231
|
-
return
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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
|
|
456
|
+
toHistoryPersistedMessages(normalizeReadChatMessages(parsed)),
|
|
282
457
|
parsed.title,
|
|
283
458
|
args?.targetSessionId,
|
|
284
459
|
historySessionId,
|
|
285
460
|
);
|
|
286
|
-
return
|
|
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 {
|
|
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
|
|
481
|
+
toHistoryPersistedMessages(normalizeReadChatMessages(parsed)),
|
|
307
482
|
parsed.title,
|
|
308
483
|
args?.targetSessionId,
|
|
309
484
|
historySessionId,
|
|
310
485
|
);
|
|
311
|
-
return
|
|
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 {
|
|
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
|
+
}
|