@adhdev/daemon-core 0.8.29 → 0.8.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-stream/manager.d.ts +1 -0
- package/dist/agent-stream/provider-adapter.d.ts +1 -0
- package/dist/agent-stream/types.d.ts +3 -0
- package/dist/boot/daemon-lifecycle.d.ts +2 -1
- package/dist/cdp/manager.d.ts +2 -0
- package/dist/cli-adapter-types.d.ts +34 -5
- package/dist/cli-adapters/provider-cli-adapter.d.ts +4 -158
- package/dist/cli-adapters/provider-cli-config.d.ts +30 -0
- package/dist/cli-adapters/provider-cli-parse.d.ts +42 -0
- package/dist/cli-adapters/provider-cli-runtime.d.ts +29 -0
- package/dist/cli-adapters/provider-cli-shared.d.ts +158 -0
- package/dist/commands/handler.d.ts +4 -3
- package/dist/config/config.d.ts +4 -3
- package/dist/index.js +1033 -621
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1035 -624
- package/dist/index.mjs.map +1 -1
- package/dist/providers/acp-provider-instance.d.ts +1 -0
- package/dist/providers/approval-utils.d.ts +7 -0
- package/dist/providers/cli-provider-instance.d.ts +2 -0
- package/dist/providers/contracts.d.ts +12 -1
- package/dist/providers/ide-provider-instance.d.ts +1 -0
- package/dist/providers/provider-loader.d.ts +3 -0
- package/dist/status/reporter.d.ts +2 -3
- package/dist/status/snapshot.d.ts +2 -1
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +3 -1
- package/src/agent-stream/manager.ts +8 -2
- package/src/agent-stream/poller.ts +57 -6
- package/src/agent-stream/provider-adapter.ts +11 -7
- package/src/agent-stream/types.ts +3 -0
- package/src/boot/daemon-lifecycle.ts +7 -6
- package/src/cdp/initializer.ts +2 -2
- package/src/cdp/manager.ts +5 -0
- package/src/cdp/setup.ts +1 -1
- package/src/cli-adapter-types.ts +37 -5
- package/src/cli-adapters/provider-cli-adapter.ts +212 -795
- package/src/cli-adapters/provider-cli-config.ts +66 -0
- package/src/cli-adapters/provider-cli-parse.ts +202 -0
- package/src/cli-adapters/provider-cli-runtime.ts +142 -0
- package/src/cli-adapters/provider-cli-shared.ts +439 -0
- package/src/cli-adapters/terminal-backends/ghostty-vt-backend.ts +1 -1
- package/src/commands/cdp-commands.ts +6 -1
- package/src/commands/chat-commands.ts +45 -29
- package/src/commands/cli-manager.ts +28 -9
- package/src/commands/handler.ts +14 -10
- package/src/commands/router.ts +23 -10
- package/src/commands/stream-commands.ts +11 -5
- package/src/config/config.ts +4 -10
- package/src/daemon/dev-auto-implement.ts +22 -18
- package/src/daemon/dev-cli-debug.ts +59 -16
- package/src/daemon/dev-server.ts +67 -43
- package/src/providers/acp-provider-instance.ts +18 -3
- package/src/providers/approval-utils.ts +66 -0
- package/src/providers/cli-provider-instance.ts +32 -6
- package/src/providers/contracts.d.ts +1 -0
- package/src/providers/contracts.ts +15 -2
- package/src/providers/extension-provider-instance.ts +1 -1
- package/src/providers/ide-provider-instance.ts +67 -41
- package/src/providers/provider-loader.ts +110 -55
- package/src/providers/version-archive.ts +23 -5
- package/src/status/reporter.ts +18 -14
- package/src/status/snapshot.ts +5 -4
|
@@ -93,6 +93,7 @@ export declare class AcpProviderInstance implements ProviderInstance {
|
|
|
93
93
|
private convertToolCallContent;
|
|
94
94
|
private detectStatusTransition;
|
|
95
95
|
private pushEvent;
|
|
96
|
+
private appendSystemMessage;
|
|
96
97
|
private flushEvents;
|
|
97
98
|
get cliType(): string;
|
|
98
99
|
get cliName(): string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ProviderModule } from './contracts.js';
|
|
2
|
+
export declare function getApprovalPositiveHints(provider?: Pick<ProviderModule, 'approvalPositiveHints'> | null): string[];
|
|
3
|
+
export declare function pickApprovalButton(buttons: string[] | null | undefined, provider?: Pick<ProviderModule, 'approvalPositiveHints'> | null): {
|
|
4
|
+
index: number;
|
|
5
|
+
label: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function formatAutoApprovalMessage(modalMessage?: string, buttonLabel?: string): string;
|
|
@@ -71,6 +71,8 @@ export declare class CliProviderInstance implements ProviderInstance {
|
|
|
71
71
|
getAdapter(): ProviderCliAdapter;
|
|
72
72
|
get cliType(): string;
|
|
73
73
|
get cliName(): string;
|
|
74
|
+
private shouldAutoApprove;
|
|
75
|
+
private recordAutoApproval;
|
|
74
76
|
recordApprovalSelection(buttonText: string): void;
|
|
75
77
|
private formatMarkerTimestamp;
|
|
76
78
|
private maybeAppendRuntimeRecoveryMessage;
|
|
@@ -233,6 +233,11 @@ export interface CdpTargetFilter {
|
|
|
233
233
|
/** Page title regex pattern for titles to EXCLUDE (e.g. 'Debug Console|Output') */
|
|
234
234
|
titleExcludes?: string;
|
|
235
235
|
}
|
|
236
|
+
export type ProviderVersionCommand = string | Partial<Record<string, string>>;
|
|
237
|
+
export interface ProviderCompatibilityEntry {
|
|
238
|
+
ideVersion: string;
|
|
239
|
+
scriptDir: string;
|
|
240
|
+
}
|
|
236
241
|
export interface ProviderModule {
|
|
237
242
|
/** Unique identifier (e.g. 'cline', 'cursor', 'gemini-cli') */
|
|
238
243
|
type: string;
|
|
@@ -255,7 +260,7 @@ export interface ProviderModule {
|
|
|
255
260
|
/** Install instructions (shown when command is missing) */
|
|
256
261
|
install?: string;
|
|
257
262
|
/** Custom version detection command (e.g. 'cursor --version', 'claude -v') */
|
|
258
|
-
versionCommand?:
|
|
263
|
+
versionCommand?: ProviderVersionCommand;
|
|
259
264
|
/** Versions tested by provider maintainer (informational) */
|
|
260
265
|
testedVersions?: string[];
|
|
261
266
|
/** Per-OS process names — used by launch.ts to detect/kill IDE processes */
|
|
@@ -296,6 +301,9 @@ export interface ProviderModule {
|
|
|
296
301
|
};
|
|
297
302
|
extensionId?: string;
|
|
298
303
|
extensionIdPattern?: RegExp;
|
|
304
|
+
extensionIdPattern_flags?: string;
|
|
305
|
+
compatibility?: ProviderCompatibilityEntry[];
|
|
306
|
+
defaultScriptDir?: string;
|
|
299
307
|
binary?: string;
|
|
300
308
|
spawn?: {
|
|
301
309
|
command: string;
|
|
@@ -303,6 +311,7 @@ export interface ProviderModule {
|
|
|
303
311
|
shell?: boolean;
|
|
304
312
|
env?: Record<string, string>;
|
|
305
313
|
};
|
|
314
|
+
approvalKeys?: Record<number, string>;
|
|
306
315
|
patterns?: {
|
|
307
316
|
prompt?: RegExp[];
|
|
308
317
|
generating?: RegExp[];
|
|
@@ -313,6 +322,8 @@ export interface ProviderModule {
|
|
|
313
322
|
resume?: ProviderResumeCapability;
|
|
314
323
|
/** Session ID probe config — auto-discovers provider session ID from local SQLite DB */
|
|
315
324
|
sessionProbe?: ProviderSessionProbe;
|
|
325
|
+
/** Approval button priority hints used when auto-approve must pick a positive action */
|
|
326
|
+
approvalPositiveHints?: string[];
|
|
316
327
|
scripts?: ProviderScripts;
|
|
317
328
|
vscodeCommands?: {
|
|
318
329
|
focusPanel?: string;
|
|
@@ -266,6 +266,9 @@ export declare class ProviderLoader {
|
|
|
266
266
|
*/
|
|
267
267
|
setSetting(type: string, key: string, value: any): boolean;
|
|
268
268
|
private getOptionalStringSetting;
|
|
269
|
+
protected readConfig(): any | null;
|
|
270
|
+
protected writeConfig(config: any): void;
|
|
271
|
+
private getPlatformVersionCommand;
|
|
269
272
|
private getSettingsSchema;
|
|
270
273
|
private getSyntheticSettings;
|
|
271
274
|
/**
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Collect status from ProviderInstanceManager → assemble payload → transmit
|
|
5
5
|
* Each Instance manages its own status/transition. This module only assembles + transmits.
|
|
6
6
|
*/
|
|
7
|
+
import type { DaemonCdpManager } from '../cdp/manager.js';
|
|
7
8
|
import type { ProviderState } from '../providers/provider-instance.js';
|
|
8
9
|
export interface StatusReporterDeps {
|
|
9
10
|
serverConn: {
|
|
@@ -11,9 +12,7 @@ export interface StatusReporterDeps {
|
|
|
11
12
|
sendMessage(type: string, data: any): void;
|
|
12
13
|
getUserPlan(): string;
|
|
13
14
|
} | null;
|
|
14
|
-
cdpManagers: Map<string,
|
|
15
|
-
isConnected: boolean;
|
|
16
|
-
}>;
|
|
15
|
+
cdpManagers: Map<string, DaemonCdpManager>;
|
|
17
16
|
p2p: {
|
|
18
17
|
isConnected: boolean;
|
|
19
18
|
isAvailable: boolean;
|
|
@@ -5,11 +5,12 @@
|
|
|
5
5
|
* - DaemonStatusReporter (cloud)
|
|
6
6
|
* - daemon-standalone HTTP/WS status responses
|
|
7
7
|
*/
|
|
8
|
+
import type { DaemonCdpManager } from '../cdp/manager.js';
|
|
8
9
|
import type { ProviderState } from '../providers/provider-instance.js';
|
|
9
10
|
import type { AvailableProviderInfo, StatusReportPayload } from '../shared-types.js';
|
|
10
11
|
export interface StatusSnapshotOptions {
|
|
11
12
|
allStates: ProviderState[];
|
|
12
|
-
cdpManagers: Map<string,
|
|
13
|
+
cdpManagers: Map<string, DaemonCdpManager>;
|
|
13
14
|
providerLoader: {
|
|
14
15
|
getAll(): Array<{
|
|
15
16
|
type: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adhdev/daemon-core",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.31",
|
|
4
4
|
"description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
"build": "tsup && npm run build:types",
|
|
23
23
|
"build:types": "tsc -p tsconfig.json --emitDeclarationOnly --declaration --declarationMap false",
|
|
24
24
|
"dev": "tsup --watch",
|
|
25
|
+
"test": "vitest run",
|
|
26
|
+
"test:watch": "vitest",
|
|
25
27
|
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
26
28
|
},
|
|
27
29
|
"files": [
|
|
@@ -121,6 +121,12 @@ export class DaemonAgentStreamManager {
|
|
|
121
121
|
return child?.sessionId || null;
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
private getStateError(state: AgentStreamState): string {
|
|
125
|
+
if (typeof state.error === 'string' && state.error.trim()) return state.error.trim();
|
|
126
|
+
if (typeof state._error === 'string' && state._error.trim()) return state._error.trim();
|
|
127
|
+
return 'unknown';
|
|
128
|
+
}
|
|
129
|
+
|
|
124
130
|
private async connectManagedSession(
|
|
125
131
|
cdp: DaemonCdpManager,
|
|
126
132
|
parentSessionId: string,
|
|
@@ -194,8 +200,8 @@ export class DaemonAgentStreamManager {
|
|
|
194
200
|
const evaluate: AgentEvaluateFn = (expr, timeout) =>
|
|
195
201
|
cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
|
|
196
202
|
const state = await agent.adapter.readChat(evaluate);
|
|
197
|
-
|
|
198
|
-
|
|
203
|
+
const stateError = this.getStateError(state);
|
|
204
|
+
LOG.debug('AgentStream', `[AgentStream] readChat(${type}) result: status=${state.status} msgs=${state.messages?.length || 0} model=${state.model || ''}${state.status === 'error' ? ' error=' + JSON.stringify(stateError) : ''}`);
|
|
199
205
|
if (state.status === 'error' && this.isRecoverableSessionError(stateError)) {
|
|
200
206
|
throw new Error(stateError);
|
|
201
207
|
}
|
|
@@ -19,6 +19,21 @@ import type { SessionRegistry } from '../sessions/registry.js';
|
|
|
19
19
|
import { reconcileIdeRuntimeSessions } from '../sessions/reconcile.js';
|
|
20
20
|
import { LOG } from '../logging/logger.js';
|
|
21
21
|
import type { AgentStreamState } from './types.js';
|
|
22
|
+
import { formatAutoApprovalMessage, pickApprovalButton } from '../providers/approval-utils.js';
|
|
23
|
+
import type { ProviderModule } from '../providers/contracts.js';
|
|
24
|
+
|
|
25
|
+
interface ExtensionInstanceLike {
|
|
26
|
+
type?: string;
|
|
27
|
+
getInstanceId?(): string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface IdeInstanceLike {
|
|
31
|
+
getInstanceId?(): string;
|
|
32
|
+
getExtensionTypes?(): string[];
|
|
33
|
+
getExtension?(type: string): ExtensionInstanceLike | undefined;
|
|
34
|
+
addExtension?(provider: ProviderModule, settings: Record<string, unknown>): void;
|
|
35
|
+
removeExtension?(type: string): void;
|
|
36
|
+
}
|
|
22
37
|
|
|
23
38
|
// ─── Types ───
|
|
24
39
|
|
|
@@ -80,7 +95,7 @@ export class AgentStreamPoller {
|
|
|
80
95
|
if (!agentStreamManager || cdpManagers.size === 0) return;
|
|
81
96
|
|
|
82
97
|
// Defensive repair: keep SessionRegistry aligned with live IDE/extension instances.
|
|
83
|
-
reconcileIdeRuntimeSessions(instanceManager
|
|
98
|
+
reconcileIdeRuntimeSessions(instanceManager, sessionRegistry);
|
|
84
99
|
|
|
85
100
|
// ─── Phase 1: Refresh extension providers + IDE instance extensions ───
|
|
86
101
|
for (const [ideType, cdp] of cdpManagers) {
|
|
@@ -88,12 +103,12 @@ export class AgentStreamPoller {
|
|
|
88
103
|
registerExtensionProviders(providerLoader, cdp, ideType);
|
|
89
104
|
|
|
90
105
|
// 1b. Dynamically add/remove IDE instance extensions
|
|
91
|
-
const ideInstance = instanceManager.getInstance(`ide:${ideType}`) as
|
|
106
|
+
const ideInstance = instanceManager.getInstance(`ide:${ideType}`) as IdeInstanceLike | undefined;
|
|
92
107
|
const parentSessionId = ideInstance?.getInstanceId?.();
|
|
93
108
|
if (ideInstance?.getExtensionTypes && ideInstance?.addExtension && ideInstance?.removeExtension) {
|
|
94
|
-
const currentExtTypes = new Set(ideInstance.getExtensionTypes()
|
|
109
|
+
const currentExtTypes = new Set(ideInstance.getExtensionTypes());
|
|
95
110
|
const enabledExtTypes = new Set(
|
|
96
|
-
providerLoader.getEnabledByCategory('extension', ideType).map((p
|
|
111
|
+
providerLoader.getEnabledByCategory('extension', ideType).map((p) => p.type)
|
|
97
112
|
);
|
|
98
113
|
|
|
99
114
|
// Remove disabled extensions
|
|
@@ -145,7 +160,7 @@ export class AgentStreamPoller {
|
|
|
145
160
|
const activeSessionId = parentSessionId ? agentStreamManager.getActiveSessionId(parentSessionId) : null;
|
|
146
161
|
if (activeSessionId) {
|
|
147
162
|
const activeTarget = sessionRegistry.get(activeSessionId);
|
|
148
|
-
const enabledExtTypes = new Set(providerLoader.getEnabledExtensionProviders(ideType).map((p
|
|
163
|
+
const enabledExtTypes = new Set(providerLoader.getEnabledExtensionProviders(ideType).map((p) => p.type));
|
|
149
164
|
if (!activeTarget || !enabledExtTypes.has(activeTarget.providerType)) {
|
|
150
165
|
LOG.info('AgentStream', `Active agent ${activeTarget?.providerType || activeSessionId} was disabled for ${ideType} — detaching`);
|
|
151
166
|
await agentStreamManager.setActiveSession(cdp, parentSessionId!, null);
|
|
@@ -189,7 +204,43 @@ export class AgentStreamPoller {
|
|
|
189
204
|
|
|
190
205
|
try {
|
|
191
206
|
await agentStreamManager.syncActiveSession(cdp, parentSessionId);
|
|
192
|
-
|
|
207
|
+
let stream = await agentStreamManager.collectActiveSession(cdp, parentSessionId);
|
|
208
|
+
if (stream?.status === 'waiting_approval') {
|
|
209
|
+
const autoApprove = providerLoader.getSettings(stream.agentType).autoApprove !== false;
|
|
210
|
+
if (autoApprove && resolvedActiveSessionId) {
|
|
211
|
+
const provider = providerLoader.getMeta(stream.agentType);
|
|
212
|
+
const { label: buttonLabel } = pickApprovalButton(stream.activeModal?.buttons, provider);
|
|
213
|
+
const approved = await agentStreamManager.resolveSessionAction(cdp, resolvedActiveSessionId, 'approve', buttonLabel);
|
|
214
|
+
if (approved) {
|
|
215
|
+
const effectId = [
|
|
216
|
+
'auto_approval',
|
|
217
|
+
resolvedActiveSessionId,
|
|
218
|
+
String(stream.messages?.length || 0),
|
|
219
|
+
buttonLabel,
|
|
220
|
+
String(stream.activeModal?.message || '').trim(),
|
|
221
|
+
].join(':');
|
|
222
|
+
stream = {
|
|
223
|
+
...stream,
|
|
224
|
+
status: 'streaming',
|
|
225
|
+
activeModal: undefined,
|
|
226
|
+
effects: [
|
|
227
|
+
...(stream.effects || []),
|
|
228
|
+
{
|
|
229
|
+
type: 'message',
|
|
230
|
+
id: effectId,
|
|
231
|
+
persist: true,
|
|
232
|
+
message: {
|
|
233
|
+
role: 'system',
|
|
234
|
+
senderName: 'System',
|
|
235
|
+
kind: 'system',
|
|
236
|
+
content: formatAutoApprovalMessage(stream.activeModal?.message, buttonLabel),
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
193
244
|
this.deps.onStreamsUpdated?.(ideType, stream ? [stream] : []);
|
|
194
245
|
} catch { }
|
|
195
246
|
}
|
|
@@ -11,7 +11,7 @@ import type {
|
|
|
11
11
|
AgentChatListItem,
|
|
12
12
|
AgentEvaluateFn,
|
|
13
13
|
} from './types.js';
|
|
14
|
-
import type { ProviderModule } from '../providers/contracts.js';
|
|
14
|
+
import type { ProviderModule, ProviderScripts } from '../providers/contracts.js';
|
|
15
15
|
import { extractProviderControlValues, normalizeProviderEffects } from '../providers/control-effects.js';
|
|
16
16
|
|
|
17
17
|
export class ProviderStreamAdapter implements IAgentStreamAdapter {
|
|
@@ -32,13 +32,17 @@ export class ProviderStreamAdapter implements IAgentStreamAdapter {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
private callScript(name: string, ...args: any[]): string | null {
|
|
35
|
-
const fn =
|
|
35
|
+
const fn = this.provider.scripts?.[name];
|
|
36
36
|
if (typeof fn !== 'function') return null;
|
|
37
37
|
return fn(...args) || null;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
private hasScript(name: string): boolean {
|
|
41
|
-
return typeof
|
|
41
|
+
return typeof this.provider.scripts?.[name] === 'function';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private getStateTitle(state: AgentStreamState): string {
|
|
45
|
+
return typeof state.title === 'string' ? state.title : '';
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
private parseMaybeJson(raw: unknown): any {
|
|
@@ -83,7 +87,7 @@ export class ProviderStreamAdapter implements IAgentStreamAdapter {
|
|
|
83
87
|
|
|
84
88
|
private lastMessageSignature(state: AgentStreamState | null | undefined): string {
|
|
85
89
|
const messages = Array.isArray(state?.messages) ? state!.messages : [];
|
|
86
|
-
const last = messages[messages.length - 1]
|
|
90
|
+
const last = messages[messages.length - 1];
|
|
87
91
|
if (!last) return '';
|
|
88
92
|
return `${last.role || ''}:${String(last.content || '').replace(/\s+/g, ' ').trim()}`;
|
|
89
93
|
}
|
|
@@ -155,7 +159,7 @@ export class ProviderStreamAdapter implements IAgentStreamAdapter {
|
|
|
155
159
|
activeModal: data.activeModal,
|
|
156
160
|
};
|
|
157
161
|
if (typeof data.title === 'string' && data.title.trim()) {
|
|
158
|
-
|
|
162
|
+
state.title = data.title.trim();
|
|
159
163
|
}
|
|
160
164
|
const controlValues = extractProviderControlValues(this.provider.controls, data);
|
|
161
165
|
if (controlValues) state.controlValues = controlValues;
|
|
@@ -282,7 +286,7 @@ export class ProviderStreamAdapter implements IAgentStreamAdapter {
|
|
|
282
286
|
for (let attempt = 0; attempt < 6; attempt += 1) {
|
|
283
287
|
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
284
288
|
const state = await this.readChat(evaluate);
|
|
285
|
-
const title =
|
|
289
|
+
const title = this.getStateTitle(state);
|
|
286
290
|
if (this.titlesMatch(title, sessionId)) return true;
|
|
287
291
|
}
|
|
288
292
|
return false;
|
|
@@ -303,6 +307,6 @@ export class ProviderStreamAdapter implements IAgentStreamAdapter {
|
|
|
303
307
|
messages: [],
|
|
304
308
|
inputContent: '',
|
|
305
309
|
_error: message,
|
|
306
|
-
}
|
|
310
|
+
};
|
|
307
311
|
}
|
|
308
312
|
}
|
|
@@ -31,11 +31,14 @@ export interface AgentStreamState {
|
|
|
31
31
|
status: 'idle' | 'streaming' | 'waiting_approval' | 'error' | 'disconnected' | 'panel_hidden' | 'not_monitored';
|
|
32
32
|
messages: AgentChatMessage[];
|
|
33
33
|
inputContent: string;
|
|
34
|
+
title?: string;
|
|
34
35
|
/** @deprecated Use controlValues['model'] — kept for backward compatibility */
|
|
35
36
|
model?: string;
|
|
36
37
|
/** @deprecated Use controlValues['mode'] — kept for backward compatibility */
|
|
37
38
|
mode?: string;
|
|
38
39
|
activeModal?: { message: string; buttons: string[] };
|
|
40
|
+
error?: string;
|
|
41
|
+
_error?: string;
|
|
39
42
|
/** Dynamic control current values (populated from readChat + provider controls schema) */
|
|
40
43
|
controlValues?: Record<string, string | number | boolean>;
|
|
41
44
|
/** Provider-driven UI effects from readChat */
|
|
@@ -24,12 +24,13 @@ import { ProviderLoader } from '../providers/provider-loader.js';
|
|
|
24
24
|
import { VersionArchive, detectAllVersions } from '../providers/version-archive.js';
|
|
25
25
|
import { ProviderInstanceManager } from '../providers/provider-instance-manager.js';
|
|
26
26
|
import { DevServer } from '../daemon/dev-server.js';
|
|
27
|
-
import { detectIDEs } from '../detection/ide-detector.js';
|
|
27
|
+
import { detectIDEs, type IDEInfo } from '../detection/ide-detector.js';
|
|
28
28
|
import { detectCLI, detectCLIs } from '../detection/cli-detector.js';
|
|
29
29
|
import { SessionRegistry } from '../sessions/registry.js';
|
|
30
30
|
import { installGlobalInterceptor, LOG } from '../logging/logger.js';
|
|
31
31
|
import { loadConfig } from '../config/config.js';
|
|
32
32
|
import type { PtyTransportFactory } from '../cli-adapters/pty-transport.js';
|
|
33
|
+
import type { IdeProviderInstance } from '../providers/ide-provider-instance.js';
|
|
33
34
|
|
|
34
35
|
// ─── Init Config ───
|
|
35
36
|
|
|
@@ -82,7 +83,7 @@ export interface DaemonComponents {
|
|
|
82
83
|
cdpInitializer: DaemonCdpInitializer;
|
|
83
84
|
cdpManagers: Map<string, DaemonCdpManager>;
|
|
84
85
|
sessionRegistry: SessionRegistry;
|
|
85
|
-
detectedIdes: { value:
|
|
86
|
+
detectedIdes: { value: IDEInfo[] };
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
export interface DaemonDevSupportOptions {
|
|
@@ -157,7 +158,7 @@ export async function initDaemonComponents(config: DaemonInitConfig): Promise<Da
|
|
|
157
158
|
const instanceManager = new ProviderInstanceManager();
|
|
158
159
|
const cdpManagers = new Map<string, DaemonCdpManager>();
|
|
159
160
|
const sessionRegistry = new SessionRegistry();
|
|
160
|
-
const detectedIdesRef
|
|
161
|
+
const detectedIdesRef: { value: IDEInfo[] } = { value: [] };
|
|
161
162
|
let agentStreamManager: DaemonAgentStreamManager | null = null;
|
|
162
163
|
let poller: AgentStreamPoller | null = null;
|
|
163
164
|
|
|
@@ -193,8 +194,8 @@ export async function initDaemonComponents(config: DaemonInitConfig): Promise<Da
|
|
|
193
194
|
// 5. Detect IDEs
|
|
194
195
|
LOG.info('Init', 'Detecting IDEs...');
|
|
195
196
|
await refreshProviderAvailability();
|
|
196
|
-
const installed = detectedIdesRef.value.filter((i
|
|
197
|
-
LOG.info('Init', `Found ${installed.length} IDE(s): ${installed.map((i
|
|
197
|
+
const installed = detectedIdesRef.value.filter((i) => i.installed);
|
|
198
|
+
LOG.info('Init', `Found ${installed.length} IDE(s): ${installed.map((i) => i.id).join(', ') || 'none'}`);
|
|
198
199
|
|
|
199
200
|
// 6. CDP Initializer — connect + register instances
|
|
200
201
|
const cdpSetupContext: CdpSetupContext = {
|
|
@@ -217,7 +218,7 @@ export async function initDaemonComponents(config: DaemonInitConfig): Promise<Da
|
|
|
217
218
|
onDisconnected: async (_ideType, _manager, managerKey) => {
|
|
218
219
|
sessionRegistry.unregisterByManagerKey(managerKey);
|
|
219
220
|
const instanceKey = `ide:${managerKey}`;
|
|
220
|
-
const ideInstance = instanceManager.getInstance(instanceKey) as
|
|
221
|
+
const ideInstance = instanceManager.getInstance(instanceKey) as IdeProviderInstance | undefined;
|
|
221
222
|
|
|
222
223
|
if (ideInstance) {
|
|
223
224
|
instanceManager.removeInstance(instanceKey);
|
package/src/cdp/initializer.ts
CHANGED
|
@@ -107,7 +107,7 @@ export class DaemonCdpInitializer {
|
|
|
107
107
|
port,
|
|
108
108
|
LOG.forComponent(`CDP:${ide}`).asLogFn(),
|
|
109
109
|
undefined,
|
|
110
|
-
|
|
110
|
+
provider?.targetFilter,
|
|
111
111
|
);
|
|
112
112
|
const connected = await manager.connect();
|
|
113
113
|
if (connected) {
|
|
@@ -148,7 +148,7 @@ export class DaemonCdpInitializer {
|
|
|
148
148
|
port,
|
|
149
149
|
LOG.forComponent(`CDP:${managerKey}`).asLogFn(),
|
|
150
150
|
target.id,
|
|
151
|
-
|
|
151
|
+
provider?.targetFilter,
|
|
152
152
|
);
|
|
153
153
|
|
|
154
154
|
const connected = await manager.connect();
|
package/src/cdp/manager.ts
CHANGED
|
@@ -77,6 +77,11 @@ export class DaemonCdpManager {
|
|
|
77
77
|
this._targetFilter = filter;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
/** Clear a previously pinned target so the next connect can reselect a page. */
|
|
81
|
+
clearTargetId(): void {
|
|
82
|
+
this._targetId = null;
|
|
83
|
+
}
|
|
84
|
+
|
|
80
85
|
/**
|
|
81
86
|
* Check if a page title should be excluded (non-main page).
|
|
82
87
|
* Uses provider-configured titleExcludes, falls back to default pattern.
|
package/src/cdp/setup.ts
CHANGED
package/src/cli-adapter-types.ts
CHANGED
|
@@ -4,15 +4,44 @@
|
|
|
4
4
|
* Contract implemented by all CLI adapters (ProviderCliAdapter etc).
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import type { ChatMessage } from './types.js';
|
|
8
|
+
|
|
9
|
+
export interface CliAdapterStatus {
|
|
10
|
+
status?: string;
|
|
11
|
+
messages?: ChatMessage[];
|
|
12
|
+
activeModal?: {
|
|
13
|
+
message: string;
|
|
14
|
+
buttons: string[];
|
|
15
|
+
} | null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface AcpAdapterHandle {
|
|
19
|
+
onEvent(event: string, data?: unknown): void;
|
|
20
|
+
getState(): {
|
|
21
|
+
status: string;
|
|
22
|
+
activeChat?: {
|
|
23
|
+
messages?: ChatMessage[];
|
|
24
|
+
activeModal?: {
|
|
25
|
+
message: string;
|
|
26
|
+
buttons: string[];
|
|
27
|
+
} | null;
|
|
28
|
+
} | null;
|
|
29
|
+
};
|
|
30
|
+
setMode?(mode: string): Promise<void>;
|
|
31
|
+
setConfigOption?(configId: string, value: string): Promise<void>;
|
|
32
|
+
resolvePermission?(approved: boolean): Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
|
|
7
35
|
export interface CliAdapter {
|
|
8
36
|
cliType: string;
|
|
9
37
|
cliName: string;
|
|
10
38
|
workingDir: string;
|
|
39
|
+
_acpInstance?: AcpAdapterHandle;
|
|
11
40
|
spawn(): Promise<void>;
|
|
12
41
|
sendMessage(text: string): Promise<void>;
|
|
13
|
-
getStatus():
|
|
14
|
-
getScriptParsedStatus?():
|
|
15
|
-
invokeScript?(scriptName: string, args?:
|
|
42
|
+
getStatus(): CliAdapterStatus;
|
|
43
|
+
getScriptParsedStatus?(): unknown;
|
|
44
|
+
invokeScript?(scriptName: string, args?: Record<string, unknown>): Promise<unknown>;
|
|
16
45
|
getPartialResponse(): string;
|
|
17
46
|
saveAndStop?(): Promise<void>;
|
|
18
47
|
shutdown(): void;
|
|
@@ -21,8 +50,11 @@ export interface CliAdapter {
|
|
|
21
50
|
isProcessing(): boolean;
|
|
22
51
|
isReady(): boolean;
|
|
23
52
|
setOnStatusChange(callback: () => void): void;
|
|
24
|
-
updateRuntimeSettings?(settings: Record<string,
|
|
25
|
-
setServerConn?(serverConn:
|
|
53
|
+
updateRuntimeSettings?(settings: Record<string, unknown>): void;
|
|
54
|
+
setServerConn?(serverConn: unknown): void;
|
|
55
|
+
clearHistory?(): void;
|
|
56
|
+
resolveAction?(data: unknown): Promise<void>;
|
|
57
|
+
resolveModal?(buttonIndex: number): void;
|
|
26
58
|
// Raw PTY I/O (for terminal view)
|
|
27
59
|
setOnPtyData?(callback: (data: string) => void): void;
|
|
28
60
|
writeRaw?(data: string): void;
|