@adhdev/daemon-core 0.8.35 → 0.8.37
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 +458 -154
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +457 -154
- package/dist/index.mjs.map +1 -1
- package/dist/shared-types.d.ts +248 -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 +4 -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/boot/daemon-lifecycle.ts +7 -0
- package/src/commands/chat-commands.ts +192 -17
- package/src/commands/router.ts +25 -0
- package/src/commands/stream-commands.ts +14 -10
- package/src/config/config.ts +8 -0
- package/src/index.d.ts +2 -2
- package/src/index.ts +32 -1
- package/src/shared-types.d.ts +125 -16
- package/src/shared-types.ts +279 -16
- package/src/status/builders.ts +110 -54
- package/src/status/normalize.ts +54 -19
- package/src/status/reporter.ts +88 -13
- package/src/status/snapshot.ts +79 -41
- package/src/types.ts +1 -1
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
* - daemon-standalone HTTP/WS status responses
|
|
7
7
|
*/
|
|
8
8
|
import type { DaemonCdpManager } from '../cdp/manager.js';
|
|
9
|
+
import { type SessionEntryProfile } from './builders.js';
|
|
9
10
|
import type { ProviderState } from '../providers/provider-instance.js';
|
|
10
|
-
import type {
|
|
11
|
+
import type { MachineInfo, StatusReportPayload } from '../shared-types.js';
|
|
11
12
|
export interface StatusSnapshotOptions {
|
|
12
13
|
allStates: ProviderState[];
|
|
13
14
|
cdpManagers: Map<string, DaemonCdpManager>;
|
|
@@ -36,14 +37,13 @@ export interface StatusSnapshotOptions {
|
|
|
36
37
|
}>;
|
|
37
38
|
instanceId: string;
|
|
38
39
|
version: string;
|
|
39
|
-
daemonMode: boolean;
|
|
40
40
|
timestamp?: number;
|
|
41
41
|
p2p?: StatusReportPayload['p2p'];
|
|
42
42
|
machineNickname?: string | null;
|
|
43
|
+
profile?: SessionEntryProfile;
|
|
43
44
|
}
|
|
44
|
-
export
|
|
45
|
-
|
|
46
|
-
}
|
|
45
|
+
export type StatusSnapshot = StatusReportPayload;
|
|
46
|
+
export declare function buildMachineInfo(profile?: 'full' | 'live' | 'metadata'): MachineInfo;
|
|
47
47
|
export declare function getSessionCompletionMarker(session: {
|
|
48
48
|
activeChat?: {
|
|
49
49
|
messages?: Array<{
|
package/dist/types.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export interface StatusResponse extends StatusReportPayload {
|
|
|
15
15
|
/** User display name from config */
|
|
16
16
|
userName?: string;
|
|
17
17
|
/** Available providers */
|
|
18
|
-
availableProviders
|
|
18
|
+
availableProviders?: AvailableProviderInfo[];
|
|
19
19
|
/** System info (legacy compat) */
|
|
20
20
|
system?: SystemInfo;
|
|
21
21
|
}
|
package/package.json
CHANGED
|
@@ -68,6 +68,11 @@ export interface DaemonInitConfig {
|
|
|
68
68
|
|
|
69
69
|
/** CDP scan interval (ms), default 30000 */
|
|
70
70
|
cdpScanIntervalMs?: number;
|
|
71
|
+
|
|
72
|
+
/** Canonical status identity used by on-demand snapshot commands */
|
|
73
|
+
statusInstanceId?: string;
|
|
74
|
+
statusVersion?: string;
|
|
75
|
+
statusDaemonMode?: boolean;
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
// ─── Result ───
|
|
@@ -276,6 +281,8 @@ export async function initDaemonComponents(config: DaemonInitConfig): Promise<Da
|
|
|
276
281
|
onStatusChange: config.onStatusChange,
|
|
277
282
|
onPostChatCommand: config.onPostChatCommand,
|
|
278
283
|
sessionHostControl: config.sessionHostControl,
|
|
284
|
+
statusInstanceId: config.statusInstanceId,
|
|
285
|
+
statusVersion: config.statusVersion,
|
|
279
286
|
getCdpLogFn: config.getCdpLogFn || ((ideType: string) => LOG.forComponent(`CDP:${ideType}`).asLogFn()),
|
|
280
287
|
});
|
|
281
288
|
|
|
@@ -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> {
|
package/src/commands/router.ts
CHANGED
|
@@ -31,6 +31,7 @@ import { logCommand } from '../logging/command-log.js';
|
|
|
31
31
|
import type { CommandLogEntry } from '../logging/command-log.js';
|
|
32
32
|
import { getRecentLogs, LOG_PATH } from '../logging/logger.js';
|
|
33
33
|
import { buildSessionEntries } from '../status/builders.js';
|
|
34
|
+
import { buildMachineInfo, buildStatusSnapshot } from '../status/snapshot.js';
|
|
34
35
|
import { getSessionCompletionMarker } from '../status/snapshot.js';
|
|
35
36
|
import { spawnDetachedDaemonUpgradeHelper } from './upgrade-helper.js';
|
|
36
37
|
import * as fs from 'fs';
|
|
@@ -71,6 +72,9 @@ export interface CommandRouterDeps {
|
|
|
71
72
|
getCdpLogFn?: (ideType: string) => (msg: string) => void;
|
|
72
73
|
/** Package name for upgrade detection ('adhdev' or '@adhdev/daemon-standalone') */
|
|
73
74
|
packageName?: string;
|
|
75
|
+
/** Canonical daemon status identity used by snapshot commands */
|
|
76
|
+
statusInstanceId?: string;
|
|
77
|
+
statusVersion?: string;
|
|
74
78
|
/** Session host control plane */
|
|
75
79
|
sessionHostControl?: SessionHostControlPlane | null;
|
|
76
80
|
}
|
|
@@ -491,6 +495,27 @@ export class DaemonCommandRouter {
|
|
|
491
495
|
return { success: true, userName: name };
|
|
492
496
|
}
|
|
493
497
|
|
|
498
|
+
case 'get_status_metadata': {
|
|
499
|
+
const snapshot = buildStatusSnapshot({
|
|
500
|
+
allStates: this.deps.instanceManager.collectAllStates(),
|
|
501
|
+
cdpManagers: this.deps.cdpManagers,
|
|
502
|
+
providerLoader: this.deps.providerLoader,
|
|
503
|
+
detectedIdes: this.deps.detectedIdes.value,
|
|
504
|
+
instanceId: this.deps.statusInstanceId || loadConfig().machineId || 'daemon',
|
|
505
|
+
version: this.deps.statusVersion || 'unknown',
|
|
506
|
+
profile: 'metadata',
|
|
507
|
+
});
|
|
508
|
+
return { success: true, status: snapshot };
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
case 'get_machine_runtime_stats': {
|
|
512
|
+
return {
|
|
513
|
+
success: true,
|
|
514
|
+
machine: buildMachineInfo('full'),
|
|
515
|
+
timestamp: Date.now(),
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
|
|
494
519
|
case 'mark_session_seen': {
|
|
495
520
|
const sessionId = args?.sessionId;
|
|
496
521
|
if (!sessionId || typeof sessionId !== 'string') {
|
|
@@ -164,13 +164,17 @@ function applyProviderPatch(h: CommandHelpers, args: any, payload: any): void {
|
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
async function executeProviderScript(h: CommandHelpers, args: any, scriptName: string): Promise<CommandResult> {
|
|
167
|
-
const
|
|
168
|
-
|
|
167
|
+
const resolvedProviderType =
|
|
168
|
+
h.currentSession?.providerType
|
|
169
|
+
|| h.currentProviderType
|
|
170
|
+
|| args?.agentType
|
|
171
|
+
|| args?.providerType;
|
|
172
|
+
if (!resolvedProviderType) return { success: false, error: 'targetSessionId or providerType is required' };
|
|
169
173
|
|
|
170
174
|
const loader = h.ctx.providerLoader;
|
|
171
175
|
if (!loader) return { success: false, error: 'ProviderLoader not initialized' };
|
|
172
|
-
const provider = loader.resolve(
|
|
173
|
-
if (!provider) return { success: false, error: `Provider not found: ${
|
|
176
|
+
const provider = loader.resolve(resolvedProviderType);
|
|
177
|
+
if (!provider) return { success: false, error: `Provider not found: ${resolvedProviderType}` };
|
|
174
178
|
|
|
175
179
|
const webviewScriptName = `webview${scriptName.charAt(0).toUpperCase() + scriptName.slice(1)}`;
|
|
176
180
|
const hasWebviewScript = provider.category === 'ide' &&
|
|
@@ -179,13 +183,13 @@ async function executeProviderScript(h: CommandHelpers, args: any, scriptName: s
|
|
|
179
183
|
const actualScriptName = hasWebviewScript ? webviewScriptName : scriptName;
|
|
180
184
|
|
|
181
185
|
if (!provider.scripts?.[actualScriptName as keyof typeof provider.scripts]) {
|
|
182
|
-
return { success: false, error: `Script '${actualScriptName}' not available for ${
|
|
186
|
+
return { success: false, error: `Script '${actualScriptName}' not available for ${resolvedProviderType}` };
|
|
183
187
|
}
|
|
184
188
|
|
|
185
189
|
const normalizedArgs = normalizeProviderScriptArgs(args);
|
|
186
190
|
|
|
187
191
|
if (provider.category === 'cli') {
|
|
188
|
-
const adapter = h.getCliAdapter(args?.targetSessionId ||
|
|
192
|
+
const adapter = h.getCliAdapter(args?.targetSessionId || resolvedProviderType);
|
|
189
193
|
if (!adapter?.invokeScript) {
|
|
190
194
|
return { success: false, error: `CLI adapter does not support script '${actualScriptName}'` };
|
|
191
195
|
}
|
|
@@ -213,8 +217,8 @@ async function executeProviderScript(h: CommandHelpers, args: any, scriptName: s
|
|
|
213
217
|
if (!scriptCode) return { success: false, error: `Script '${actualScriptName}' returned null` };
|
|
214
218
|
|
|
215
219
|
const cdpKey = provider.category === 'ide'
|
|
216
|
-
? (h.currentSession?.cdpManagerKey || h.currentManagerKey ||
|
|
217
|
-
: (h.currentSession?.cdpManagerKey || h.currentManagerKey
|
|
220
|
+
? (h.currentSession?.cdpManagerKey || h.currentManagerKey || resolvedProviderType)
|
|
221
|
+
: (h.currentSession?.cdpManagerKey || h.currentManagerKey);
|
|
218
222
|
LOG.info('Command', `[ExtScript] provider=${provider.type} category=${provider.category} cdpKey=${cdpKey}`);
|
|
219
223
|
const cdp = h.getCdp(cdpKey);
|
|
220
224
|
if (!cdp?.isConnected) return { success: false, error: `No CDP connection for ${cdpKey || 'any'}` };
|
|
@@ -224,7 +228,7 @@ async function executeProviderScript(h: CommandHelpers, args: any, scriptName: s
|
|
|
224
228
|
|
|
225
229
|
if (provider.category === 'extension') {
|
|
226
230
|
const runtimeSessionId = h.currentSession?.sessionId || args?.targetSessionId;
|
|
227
|
-
if (!runtimeSessionId) return { success: false, error: `No target session found for ${
|
|
231
|
+
if (!runtimeSessionId) return { success: false, error: `No target session found for ${resolvedProviderType}` };
|
|
228
232
|
const parentSessionId = h.currentSession?.parentSessionId;
|
|
229
233
|
if (parentSessionId) {
|
|
230
234
|
await h.agentStream?.setActiveSession(cdp, parentSessionId, runtimeSessionId);
|
|
@@ -257,7 +261,7 @@ async function executeProviderScript(h: CommandHelpers, args: any, scriptName: s
|
|
|
257
261
|
}
|
|
258
262
|
} else {
|
|
259
263
|
if (!targetSessionId) {
|
|
260
|
-
return { success: false, error: `No active session found for ${
|
|
264
|
+
return { success: false, error: `No active session found for ${resolvedProviderType}` };
|
|
261
265
|
}
|
|
262
266
|
result = await cdp.evaluateInSessionFrame(targetSessionId, scriptCode);
|
|
263
267
|
}
|
package/src/config/config.ts
CHANGED
|
@@ -18,6 +18,12 @@ export interface ADHDevConfig {
|
|
|
18
18
|
// Server connection
|
|
19
19
|
serverUrl: string;
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Allow server-relayed REST/API commands to reach the daemon.
|
|
23
|
+
* Disabled by default so cloud dashboard traffic stays P2P-only.
|
|
24
|
+
*/
|
|
25
|
+
allowServerApiProxy?: boolean;
|
|
26
|
+
|
|
21
27
|
// Selected IDE (primary)
|
|
22
28
|
selectedIde: string | null;
|
|
23
29
|
|
|
@@ -90,6 +96,7 @@ export interface ADHDevConfig {
|
|
|
90
96
|
|
|
91
97
|
const DEFAULT_CONFIG: ADHDevConfig = {
|
|
92
98
|
serverUrl: 'https://api.adhf.dev',
|
|
99
|
+
allowServerApiProxy: false,
|
|
93
100
|
selectedIde: null,
|
|
94
101
|
configuredIdes: [],
|
|
95
102
|
installedExtensions: [],
|
|
@@ -140,6 +147,7 @@ function normalizeConfig(raw: unknown): ADHDevConfig & { activeWorkspaceId?: str
|
|
|
140
147
|
serverUrl: typeof parsed.serverUrl === 'string' && parsed.serverUrl.trim()
|
|
141
148
|
? parsed.serverUrl
|
|
142
149
|
: DEFAULT_CONFIG.serverUrl,
|
|
150
|
+
allowServerApiProxy: asBoolean(parsed.allowServerApiProxy, DEFAULT_CONFIG.allowServerApiProxy ?? false),
|
|
143
151
|
selectedIde: asNullableString(parsed.selectedIde),
|
|
144
152
|
configuredIdes: asStringArray(parsed.configuredIdes),
|
|
145
153
|
installedExtensions: asStringArray(parsed.installedExtensions),
|
package/src/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Core logic for daemon: CDP, Provider, IDE detection, CLI/ACP adapters and more.
|
|
5
5
|
*/
|
|
6
6
|
export type { ChatMessage, ExtensionInfo, CommandResult as CoreCommandResult, ProviderConfig, DaemonEvent, StatusResponse, SystemInfo, DetectedIde, ProviderInfo, AgentEntry, } from './types.js';
|
|
7
|
-
export type { SessionEntry, CompactSessionEntry, CompactDaemonEntry, SessionTransport, SessionKind, SessionCapability, AgentSessionStream, AvailableProviderInfo, AcpConfigOption, AcpMode, ProviderControlSchema, StatusReportPayload, MachineInfo, DetectedIdeInfo, WorkspaceEntry, ProviderStatus, ProviderErrorReason, ActiveChatData, IdeProviderState, CliProviderState, AcpProviderState, ExtensionProviderState, } from './shared-types.js';
|
|
7
|
+
export type { SessionEntry, CompactSessionEntry, CompactDaemonEntry, SessionTransport, SessionKind, SessionCapability, AgentSessionStream, ReadChatCursor, ReadChatSyncMode, ReadChatSyncResult, TransportTopic, SessionChatTailSubscriptionParams, MachineRuntimeSubscriptionParams, SessionHostDiagnosticsSubscriptionParams, SessionModalSubscriptionParams, DaemonMetadataSubscriptionParams, SessionChatTailUpdate, MachineRuntimeUpdate, SessionHostDiagnosticsUpdate, SessionModalUpdate, DaemonMetadataUpdate, TopicUpdateEnvelope, SubscribeRequest, UnsubscribeRequest, StandaloneWsStatusPayload, AvailableProviderInfo, AcpConfigOption, AcpMode, ProviderControlSchema, StatusReportPayload, MachineInfo, SessionHostDiagnosticsSnapshot, SessionHostRecord, SessionHostWriteOwner, SessionHostAttachedClient, SessionHostLogEntry, SessionHostRequestTrace, SessionHostRuntimeTransition, DetectedIdeInfo, WorkspaceEntry, ProviderState, ProviderStatus, ProviderErrorReason, ActiveChatData, IdeProviderState, CliProviderState, AcpProviderState, ExtensionProviderState, } from './shared-types.js';
|
|
8
8
|
import type { RuntimeWriteOwner as _RuntimeWriteOwner } from './shared-types-extra.js';
|
|
9
9
|
import type { RuntimeAttachedClient as _RuntimeAttachedClient } from './shared-types-extra.js';
|
|
10
10
|
import type { RecentLaunchEntry as _RecentLaunchEntry } from './shared-types.js';
|
|
@@ -45,7 +45,7 @@ export { maybeRunDaemonUpgradeHelperFromEnv, spawnDetachedDaemonUpgradeHelper }
|
|
|
45
45
|
export type { DaemonUpgradeHelperPayload } from './commands/upgrade-helper.js';
|
|
46
46
|
export { DaemonStatusReporter } from './status/reporter.js';
|
|
47
47
|
export { buildSessionEntries, findCdpManager, hasCdpManager, isCdpConnected } from './status/builders.js';
|
|
48
|
-
export { buildStatusSnapshot } from './status/snapshot.js';
|
|
48
|
+
export { buildStatusSnapshot, buildMachineInfo } from './status/snapshot.js';
|
|
49
49
|
export { normalizeManagedStatus, isManagedStatusWorking, isManagedStatusWaiting, normalizeActiveChatData } from './status/normalize.js';
|
|
50
50
|
export type { ManagedStatus } from './status/normalize.js';
|
|
51
51
|
export type { StatusSnapshotOptions, StatusSnapshot } from './status/snapshot.js';
|
package/src/index.ts
CHANGED
|
@@ -23,18 +23,49 @@ export type {
|
|
|
23
23
|
SessionEntry,
|
|
24
24
|
CompactSessionEntry,
|
|
25
25
|
CompactDaemonEntry,
|
|
26
|
+
CloudDaemonSummaryEntry,
|
|
27
|
+
DashboardBootstrapDaemonEntry,
|
|
28
|
+
CloudStatusReportPayload,
|
|
29
|
+
DaemonStatusEventPayload,
|
|
30
|
+
DashboardStatusEventPayload,
|
|
26
31
|
SessionTransport,
|
|
27
32
|
SessionKind,
|
|
28
33
|
SessionCapability,
|
|
29
34
|
AgentSessionStream,
|
|
35
|
+
ReadChatCursor,
|
|
36
|
+
ReadChatSyncMode,
|
|
37
|
+
ReadChatSyncResult,
|
|
38
|
+
TransportTopic,
|
|
39
|
+
SessionChatTailSubscriptionParams,
|
|
40
|
+
MachineRuntimeSubscriptionParams,
|
|
41
|
+
SessionHostDiagnosticsSubscriptionParams,
|
|
42
|
+
SessionModalSubscriptionParams,
|
|
43
|
+
DaemonMetadataSubscriptionParams,
|
|
44
|
+
SessionChatTailUpdate,
|
|
45
|
+
MachineRuntimeUpdate,
|
|
46
|
+
SessionHostDiagnosticsUpdate,
|
|
47
|
+
SessionModalUpdate,
|
|
48
|
+
DaemonMetadataUpdate,
|
|
49
|
+
TopicUpdateEnvelope,
|
|
50
|
+
SubscribeRequest,
|
|
51
|
+
UnsubscribeRequest,
|
|
52
|
+
StandaloneWsStatusPayload,
|
|
30
53
|
AvailableProviderInfo,
|
|
31
54
|
AcpConfigOption,
|
|
32
55
|
AcpMode,
|
|
33
56
|
ProviderControlSchema,
|
|
34
57
|
StatusReportPayload,
|
|
35
58
|
MachineInfo,
|
|
59
|
+
SessionHostDiagnosticsSnapshot,
|
|
60
|
+
SessionHostRecord,
|
|
61
|
+
SessionHostWriteOwner,
|
|
62
|
+
SessionHostAttachedClient,
|
|
63
|
+
SessionHostLogEntry,
|
|
64
|
+
SessionHostRequestTrace,
|
|
65
|
+
SessionHostRuntimeTransition,
|
|
36
66
|
DetectedIdeInfo,
|
|
37
67
|
WorkspaceEntry,
|
|
68
|
+
ProviderState,
|
|
38
69
|
ProviderStatus,
|
|
39
70
|
ProviderErrorReason,
|
|
40
71
|
ActiveChatData,
|
|
@@ -103,7 +134,7 @@ export type { DaemonUpgradeHelperPayload } from './commands/upgrade-helper.js';
|
|
|
103
134
|
// ── Status ──
|
|
104
135
|
export { DaemonStatusReporter } from './status/reporter.js';
|
|
105
136
|
export { buildSessionEntries, findCdpManager, hasCdpManager, isCdpConnected } from './status/builders.js';
|
|
106
|
-
export { buildStatusSnapshot } from './status/snapshot.js';
|
|
137
|
+
export { buildStatusSnapshot, buildMachineInfo } from './status/snapshot.js';
|
|
107
138
|
export { normalizeManagedStatus, isManagedStatusWorking, isManagedStatusWaiting, normalizeActiveChatData } from './status/normalize.js';
|
|
108
139
|
export type { ManagedStatus } from './status/normalize.js';
|
|
109
140
|
export type { StatusSnapshotOptions, StatusSnapshot } from './status/snapshot.js';
|