@adhdev/daemon-core 0.7.6 → 0.7.7
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/index.d.mts +158 -38
- package/dist/index.d.ts +158 -38
- package/dist/index.js +3965 -2521
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3455 -2011
- package/dist/index.mjs.map +1 -1
- package/dist/{normalize-tKg8IiDk.d.mts → normalize-auJAPmKy.d.mts} +669 -629
- package/dist/{normalize-tKg8IiDk.d.ts → normalize-auJAPmKy.d.ts} +669 -629
- package/dist/status/normalize.d.mts +1 -1
- package/dist/status/normalize.d.ts +1 -1
- package/package.json +5 -1
- package/src/boot/daemon-lifecycle.ts +7 -4
- package/src/cli-adapter-types.ts +2 -0
- package/src/cli-adapters/provider-cli-adapter.ts +148 -11
- package/src/cli-adapters/pty-transport.ts +100 -0
- package/src/cli-adapters/session-host-transport.ts +392 -0
- package/src/cli-adapters/terminal-backends/ghostty-vt-backend.ts +126 -0
- package/src/cli-adapters/terminal-backends/types.ts +17 -0
- package/src/cli-adapters/terminal-backends/xterm-backend.ts +87 -0
- package/src/cli-adapters/terminal-screen.ts +40 -53
- package/src/commands/cli-manager.ts +184 -55
- package/src/config/config.d.ts +116 -0
- package/src/config/workspace-activity.d.ts +22 -0
- package/src/config/workspaces.d.ts +84 -0
- package/src/daemon/dev-auto-implement.ts +1087 -0
- package/src/daemon/dev-cdp-handlers.ts +1003 -0
- package/src/daemon/dev-cli-debug.ts +288 -0
- package/src/daemon/dev-server-types.ts +45 -0
- package/src/daemon/dev-server.ts +121 -1698
- package/src/index.ts +5 -1
- package/src/providers/cli-provider-instance.ts +13 -1
- package/src/providers/contracts.d.ts +408 -0
- package/src/providers/contracts.ts +9 -0
- package/src/providers/provider-instance-manager.ts +21 -0
- package/src/providers/provider-instance.d.ts +142 -0
- package/src/providers/provider-instance.ts +23 -1
- package/src/shared-types.d.ts +157 -0
- package/src/shared-types.ts +14 -0
- package/src/status/builders.ts +6 -0
- package/src/status/normalize.d.ts +14 -0
- package/src/types.d.ts +127 -0
package/src/index.ts
CHANGED
|
@@ -110,7 +110,7 @@ export { ProviderInstanceManager } from './providers/provider-instance-manager.j
|
|
|
110
110
|
export { IdeProviderInstance } from './providers/ide-provider-instance.js';
|
|
111
111
|
export { CliProviderInstance } from './providers/cli-provider-instance.js';
|
|
112
112
|
export { AcpProviderInstance } from './providers/acp-provider-instance.js';
|
|
113
|
-
export type { ProviderModule, CdpTargetFilter } from './providers/contracts.js';
|
|
113
|
+
export type { ProviderModule, CdpTargetFilter, ProviderResumeCapability } from './providers/contracts.js';
|
|
114
114
|
export { VersionArchive, detectAllVersions } from './providers/version-archive.js';
|
|
115
115
|
export type { ProviderVersionInfo, VersionHistory } from './providers/version-archive.js';
|
|
116
116
|
|
|
@@ -120,6 +120,10 @@ export { DevServer } from './daemon/dev-server.js';
|
|
|
120
120
|
// ── CLI Adapters ──
|
|
121
121
|
export { ProviderCliAdapter } from './cli-adapters/provider-cli-adapter.js';
|
|
122
122
|
export type { CliAdapter } from './cli-adapter-types.js';
|
|
123
|
+
export { NodePtyTransportFactory } from './cli-adapters/pty-transport.js';
|
|
124
|
+
export type { PtyRuntimeTransport, PtyTransportFactory, PtySpawnOptions } from './cli-adapters/pty-transport.js';
|
|
125
|
+
export { SessionHostPtyTransportFactory } from './cli-adapters/session-host-transport.js';
|
|
126
|
+
export type { HostedCliRuntimeDescriptor, CliTransportFactoryParams } from './commands/cli-manager.js';
|
|
123
127
|
|
|
124
128
|
// ── Installer ──
|
|
125
129
|
export { getAIExtensions, installExtensions, launchIDE, isExtensionInstalled } from './installer.js';
|
|
@@ -11,6 +11,7 @@ import type { ProviderModule } from './contracts.js';
|
|
|
11
11
|
import type { ProviderInstance, ProviderState, ProviderEvent, InstanceContext } from './provider-instance.js';
|
|
12
12
|
import { ProviderCliAdapter } from '../cli-adapters/provider-cli-adapter.js';
|
|
13
13
|
import type { CliProviderModule } from '../cli-adapters/provider-cli-adapter.js';
|
|
14
|
+
import type { PtyTransportFactory } from '../cli-adapters/pty-transport.js';
|
|
14
15
|
import { StatusMonitor } from './status-monitor.js';
|
|
15
16
|
import { ChatHistoryWriter } from '../config/chat-history.js';
|
|
16
17
|
import { LOG } from '../logging/logger.js';
|
|
@@ -37,10 +38,11 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
37
38
|
private workingDir: string,
|
|
38
39
|
private cliArgs: string[] = [],
|
|
39
40
|
instanceId?: string,
|
|
41
|
+
transportFactory?: PtyTransportFactory,
|
|
40
42
|
) {
|
|
41
43
|
this.type = provider.type;
|
|
42
44
|
this.instanceId = instanceId || crypto.randomUUID();
|
|
43
|
-
this.adapter = new ProviderCliAdapter(provider as any as CliProviderModule, workingDir, cliArgs);
|
|
45
|
+
this.adapter = new ProviderCliAdapter(provider as any as CliProviderModule, workingDir, cliArgs, transportFactory);
|
|
44
46
|
this.monitor = new StatusMonitor();
|
|
45
47
|
this.historyWriter = new ChatHistoryWriter();
|
|
46
48
|
}
|
|
@@ -82,6 +84,7 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
82
84
|
|
|
83
85
|
getState(): ProviderState {
|
|
84
86
|
const adapterStatus = this.adapter.getStatus();
|
|
87
|
+
const runtime = this.adapter.getRuntimeMetadata();
|
|
85
88
|
|
|
86
89
|
const dirName = this.workingDir.split('/').filter(Boolean).pop() || 'session';
|
|
87
90
|
|
|
@@ -114,6 +117,15 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
114
117
|
lastUpdated: Date.now(),
|
|
115
118
|
settings: this.settings,
|
|
116
119
|
pendingEvents: this.flushEvents(),
|
|
120
|
+
runtime: runtime ? {
|
|
121
|
+
runtimeId: runtime.runtimeId,
|
|
122
|
+
runtimeKey: runtime.runtimeKey,
|
|
123
|
+
displayName: runtime.displayName,
|
|
124
|
+
workspaceLabel: runtime.workspaceLabel,
|
|
125
|
+
writeOwner: runtime.writeOwner || null,
|
|
126
|
+
attachedClients: runtime.attachedClients || [],
|
|
127
|
+
} : undefined,
|
|
128
|
+
resume: this.provider.resume,
|
|
117
129
|
};
|
|
118
130
|
}
|
|
119
131
|
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider Output Contracts — Output contracts all providers must conform to
|
|
3
|
+
*
|
|
4
|
+
* Design principles:
|
|
5
|
+
* - Only output format is standardized; implementation is free
|
|
6
|
+
* - Common across all categories (cli, ide, extension)
|
|
7
|
+
* - User custom providers use the same contracts
|
|
8
|
+
*/
|
|
9
|
+
export interface ReadChatResult {
|
|
10
|
+
messages: ChatMessage[];
|
|
11
|
+
status: AgentStatus;
|
|
12
|
+
activeModal?: ModalInfo | null;
|
|
13
|
+
/** IDE/Extension only: session info */
|
|
14
|
+
id?: string;
|
|
15
|
+
title?: string;
|
|
16
|
+
/** Extension only: additional metadata */
|
|
17
|
+
agentType?: string;
|
|
18
|
+
agentName?: string;
|
|
19
|
+
extensionId?: string;
|
|
20
|
+
/** Status metadata */
|
|
21
|
+
isVisible?: boolean;
|
|
22
|
+
isWelcomeScreen?: boolean;
|
|
23
|
+
inputContent?: string;
|
|
24
|
+
model?: string;
|
|
25
|
+
autoApprove?: string;
|
|
26
|
+
}
|
|
27
|
+
import type { ChatMessage } from '../types.js';
|
|
28
|
+
export type { ChatMessage };
|
|
29
|
+
export type AgentStatus = 'idle' | 'generating' | 'waiting_approval' | 'error' | 'panel_hidden' | 'streaming';
|
|
30
|
+
export interface ModalInfo {
|
|
31
|
+
message: string;
|
|
32
|
+
buttons: string[];
|
|
33
|
+
width?: number;
|
|
34
|
+
height?: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* ContentBlock — ACP ContentBlock union type
|
|
38
|
+
* Represents displayable content in messages, tool call results, etc.
|
|
39
|
+
*/
|
|
40
|
+
export type ContentBlock = TextBlock | ImageBlock | AudioBlock | ResourceLinkBlock | ResourceBlock;
|
|
41
|
+
/** Text content — ACP TextContent */
|
|
42
|
+
export interface TextBlock {
|
|
43
|
+
type: 'text';
|
|
44
|
+
text: string;
|
|
45
|
+
annotations?: ContentAnnotations;
|
|
46
|
+
}
|
|
47
|
+
/** Image content — ACP ImageContent */
|
|
48
|
+
export interface ImageBlock {
|
|
49
|
+
type: 'image';
|
|
50
|
+
data: string;
|
|
51
|
+
mimeType: string;
|
|
52
|
+
uri?: string;
|
|
53
|
+
annotations?: ContentAnnotations;
|
|
54
|
+
}
|
|
55
|
+
/** Audio content — ACP AudioContent */
|
|
56
|
+
export interface AudioBlock {
|
|
57
|
+
type: 'audio';
|
|
58
|
+
data: string;
|
|
59
|
+
mimeType: string;
|
|
60
|
+
annotations?: ContentAnnotations;
|
|
61
|
+
}
|
|
62
|
+
/** Resource link (file reference) — ACP ResourceLink */
|
|
63
|
+
export interface ResourceLinkBlock {
|
|
64
|
+
type: 'resource_link';
|
|
65
|
+
uri: string;
|
|
66
|
+
name: string;
|
|
67
|
+
title?: string;
|
|
68
|
+
description?: string;
|
|
69
|
+
mimeType?: string;
|
|
70
|
+
size?: number;
|
|
71
|
+
annotations?: ContentAnnotations;
|
|
72
|
+
}
|
|
73
|
+
/** Embedded resource (inline file) — ACP EmbeddedResource */
|
|
74
|
+
export interface ResourceBlock {
|
|
75
|
+
type: 'resource';
|
|
76
|
+
resource: TextResourceContents | BlobResourceContents;
|
|
77
|
+
annotations?: ContentAnnotations;
|
|
78
|
+
}
|
|
79
|
+
export interface TextResourceContents {
|
|
80
|
+
uri: string;
|
|
81
|
+
text: string;
|
|
82
|
+
mimeType?: string | null;
|
|
83
|
+
}
|
|
84
|
+
export interface BlobResourceContents {
|
|
85
|
+
uri: string;
|
|
86
|
+
blob: string;
|
|
87
|
+
mimeType?: string | null;
|
|
88
|
+
}
|
|
89
|
+
export interface ContentAnnotations {
|
|
90
|
+
audience?: ('user' | 'assistant')[];
|
|
91
|
+
priority?: number;
|
|
92
|
+
}
|
|
93
|
+
/** Tool call info — ACP ToolCall */
|
|
94
|
+
export interface ToolCallInfo {
|
|
95
|
+
toolCallId: string;
|
|
96
|
+
title: string;
|
|
97
|
+
kind?: ToolKind;
|
|
98
|
+
status?: ToolCallStatus;
|
|
99
|
+
rawInput?: unknown;
|
|
100
|
+
rawOutput?: unknown;
|
|
101
|
+
content?: ToolCallContent[];
|
|
102
|
+
locations?: ToolCallLocation[];
|
|
103
|
+
}
|
|
104
|
+
export type ToolKind = 'read' | 'edit' | 'delete' | 'move' | 'search' | 'execute' | 'think' | 'fetch' | 'switch_mode' | 'other';
|
|
105
|
+
export type ToolCallStatus = 'pending' | 'in_progress' | 'completed' | 'failed';
|
|
106
|
+
/** Content produced by a tool call — ACP ToolCallContent */
|
|
107
|
+
export type ToolCallContent = {
|
|
108
|
+
type: 'content';
|
|
109
|
+
content: ContentBlock;
|
|
110
|
+
} | {
|
|
111
|
+
type: 'diff';
|
|
112
|
+
path: string;
|
|
113
|
+
oldText?: string;
|
|
114
|
+
newText: string;
|
|
115
|
+
} | {
|
|
116
|
+
type: 'terminal';
|
|
117
|
+
terminalId: string;
|
|
118
|
+
};
|
|
119
|
+
export interface ToolCallLocation {
|
|
120
|
+
path: string;
|
|
121
|
+
line?: number | null;
|
|
122
|
+
}
|
|
123
|
+
/** Normalize content: string → ContentBlock[] */
|
|
124
|
+
export declare function normalizeContent(content: string | ContentBlock[]): ContentBlock[];
|
|
125
|
+
/** Flatten ContentBlock[] → string (backward compat / plain-text extraction) */
|
|
126
|
+
export declare function flattenContent(content: string | ContentBlock[]): string;
|
|
127
|
+
/** SendMessage params — supports rich content (ACP PromptRequest compatible) */
|
|
128
|
+
export interface SendMessageParams {
|
|
129
|
+
/** Shortcut: text-only message */
|
|
130
|
+
text?: string;
|
|
131
|
+
/** Rich content blocks (ACP ContentBlock[]) */
|
|
132
|
+
prompt?: ContentBlock[];
|
|
133
|
+
}
|
|
134
|
+
export interface SendMessageResult {
|
|
135
|
+
sent: boolean;
|
|
136
|
+
error?: string;
|
|
137
|
+
/** When CDP Input API is needed (Lexical editor etc) */
|
|
138
|
+
needsTypeAndSend?: boolean;
|
|
139
|
+
selector?: string;
|
|
140
|
+
}
|
|
141
|
+
export interface ListSessionsResult {
|
|
142
|
+
sessions: SessionInfo[];
|
|
143
|
+
}
|
|
144
|
+
export interface SessionInfo {
|
|
145
|
+
id: string;
|
|
146
|
+
title: string;
|
|
147
|
+
time?: string;
|
|
148
|
+
}
|
|
149
|
+
export interface SwitchSessionResult {
|
|
150
|
+
switched: boolean;
|
|
151
|
+
/** When CDP click coordinates are needed (Antigravity QuickInput etc) */
|
|
152
|
+
action?: 'click';
|
|
153
|
+
clickX?: number;
|
|
154
|
+
clickY?: number;
|
|
155
|
+
error?: string;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Method 1: Script-Click — script calls el.click() directly
|
|
159
|
+
* Cursor Suitable for IDEs using div.cursor-pointer elements.
|
|
160
|
+
*/
|
|
161
|
+
export interface ResolveActionScriptClick {
|
|
162
|
+
resolved: boolean;
|
|
163
|
+
clicked?: string;
|
|
164
|
+
available?: string[];
|
|
165
|
+
error?: string;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Method 2: Coordinate-Click — returns coordinates, daemon performs CDP mouse click
|
|
169
|
+
* Antigravity Suitable for IDEs where el.click() does not work.
|
|
170
|
+
*/
|
|
171
|
+
export interface ResolveActionCoordinateClick {
|
|
172
|
+
found: boolean;
|
|
173
|
+
text?: string;
|
|
174
|
+
x?: number;
|
|
175
|
+
y?: number;
|
|
176
|
+
w?: number;
|
|
177
|
+
h?: number;
|
|
178
|
+
}
|
|
179
|
+
export type ResolveActionResult = ResolveActionScriptClick | ResolveActionCoordinateClick;
|
|
180
|
+
export type ProviderCategory = 'cli' | 'ide' | 'extension' | 'acp';
|
|
181
|
+
/**
|
|
182
|
+
* Type of object exported by module.exports in provider.js.
|
|
183
|
+
*
|
|
184
|
+
* Each provider.js is fully independent and does not import other providers.
|
|
185
|
+
* Helpers (_helpers/) can be optionally used.
|
|
186
|
+
*/
|
|
187
|
+
/**
|
|
188
|
+
* Provider-configurable CDP target filter.
|
|
189
|
+
* Used by DaemonCdpManager to select the correct page/tab to connect to.
|
|
190
|
+
* Without this, the manager uses a hardcoded default filter.
|
|
191
|
+
*/
|
|
192
|
+
export interface CdpTargetFilter {
|
|
193
|
+
/** URL must include this string (e.g. 'workbench.html') */
|
|
194
|
+
urlIncludes?: string;
|
|
195
|
+
/** URL must NOT include any of these strings */
|
|
196
|
+
urlExcludes?: string[];
|
|
197
|
+
/** Page title regex pattern for titles to EXCLUDE (e.g. 'Debug Console|Output') */
|
|
198
|
+
titleExcludes?: string;
|
|
199
|
+
}
|
|
200
|
+
export interface ProviderModule {
|
|
201
|
+
/** Unique identifier (e.g. 'cline', 'cursor', 'gemini-cli') */
|
|
202
|
+
type: string;
|
|
203
|
+
/** Display name (e.g. 'Cline', 'Cursor') */
|
|
204
|
+
name: string;
|
|
205
|
+
/** Category: determines execution method */
|
|
206
|
+
category: ProviderCategory;
|
|
207
|
+
/** Alias list — allows users to invoke by alternate names (e.g. ['claude', 'claude-code']) */
|
|
208
|
+
aliases?: string[];
|
|
209
|
+
/** CDP ports [primary, secondary] (IDE category only) */
|
|
210
|
+
cdpPorts?: [number, number];
|
|
211
|
+
/** CDP target filter — controls which page/tab to connect to (IDE category only) */
|
|
212
|
+
targetFilter?: CdpTargetFilter;
|
|
213
|
+
/** CLI command (e.g. 'cursor', 'code') */
|
|
214
|
+
cli?: string;
|
|
215
|
+
/** Display icon */
|
|
216
|
+
icon?: string;
|
|
217
|
+
/** Display name (short name) */
|
|
218
|
+
displayName?: string;
|
|
219
|
+
/** Install instructions (shown when command is missing) */
|
|
220
|
+
install?: string;
|
|
221
|
+
/** Custom version detection command (e.g. 'cursor --version', 'claude -v') */
|
|
222
|
+
versionCommand?: string;
|
|
223
|
+
/** Versions tested by provider maintainer (informational) */
|
|
224
|
+
testedVersions?: string[];
|
|
225
|
+
/** Per-OS process names — used by launch.ts to detect/kill IDE processes */
|
|
226
|
+
processNames?: {
|
|
227
|
+
darwin?: string;
|
|
228
|
+
win32?: string[];
|
|
229
|
+
linux?: string[];
|
|
230
|
+
[key: string]: string | string[] | undefined;
|
|
231
|
+
};
|
|
232
|
+
/** Per-OS install paths — used by detector.ts to detect IDE installation */
|
|
233
|
+
paths?: {
|
|
234
|
+
darwin?: string[];
|
|
235
|
+
win32?: string[];
|
|
236
|
+
linux?: string[];
|
|
237
|
+
[key: string]: string[] | undefined;
|
|
238
|
+
};
|
|
239
|
+
extensionId?: string;
|
|
240
|
+
extensionIdPattern?: RegExp;
|
|
241
|
+
binary?: string;
|
|
242
|
+
spawn?: {
|
|
243
|
+
command: string;
|
|
244
|
+
args?: string[];
|
|
245
|
+
shell?: boolean;
|
|
246
|
+
env?: Record<string, string>;
|
|
247
|
+
};
|
|
248
|
+
patterns?: {
|
|
249
|
+
prompt?: RegExp[];
|
|
250
|
+
generating?: RegExp[];
|
|
251
|
+
approval?: RegExp[];
|
|
252
|
+
ready?: RegExp[];
|
|
253
|
+
};
|
|
254
|
+
cleanOutput?: (raw: string, lastUserInput?: string) => string;
|
|
255
|
+
resume?: ProviderResumeCapability;
|
|
256
|
+
scripts?: ProviderScripts;
|
|
257
|
+
vscodeCommands?: {
|
|
258
|
+
focusPanel?: string;
|
|
259
|
+
openPanel?: string;
|
|
260
|
+
[key: string]: string | undefined;
|
|
261
|
+
};
|
|
262
|
+
inputMethod?: 'cdp-type-and-send' | 'script';
|
|
263
|
+
inputSelector?: string;
|
|
264
|
+
/** webview iframe match text (must be contained in body) */
|
|
265
|
+
webviewMatchText?: string;
|
|
266
|
+
os?: {
|
|
267
|
+
[platform: string]: Partial<Pick<ProviderModule, 'scripts' | 'inputMethod' | 'inputSelector'>>;
|
|
268
|
+
};
|
|
269
|
+
/** Key: semver range string (e.g. '< 1.107.0', '>= 2.0.0') */
|
|
270
|
+
versions?: {
|
|
271
|
+
[versionRange: string]: Partial<Pick<ProviderModule, 'scripts'>> & {
|
|
272
|
+
/**
|
|
273
|
+
* Load scripts from a subdirectory instead of scripts.js root.
|
|
274
|
+
* Path is relative to the provider directory (e.g. 'scripts/legacy').
|
|
275
|
+
* The subdirectory should contain its own scripts.js or individual .js files.
|
|
276
|
+
*/
|
|
277
|
+
__dir?: string;
|
|
278
|
+
};
|
|
279
|
+
};
|
|
280
|
+
overrides?: Array<{
|
|
281
|
+
when: {
|
|
282
|
+
os?: string;
|
|
283
|
+
version?: string;
|
|
284
|
+
};
|
|
285
|
+
scripts?: Partial<ProviderScripts>;
|
|
286
|
+
/** Load scripts from a subdirectory for this OS+version combination */
|
|
287
|
+
__dir?: string;
|
|
288
|
+
}>;
|
|
289
|
+
settings?: Record<string, ProviderSettingDef>;
|
|
290
|
+
/** Static options used when agent does not provide configOptions */
|
|
291
|
+
staticConfigOptions?: Array<{
|
|
292
|
+
category: 'model' | 'mode' | 'thought_level' | 'other';
|
|
293
|
+
configId: string;
|
|
294
|
+
defaultValue?: string;
|
|
295
|
+
options: Array<{
|
|
296
|
+
value: string;
|
|
297
|
+
name: string;
|
|
298
|
+
description?: string;
|
|
299
|
+
group?: string;
|
|
300
|
+
}>;
|
|
301
|
+
}>;
|
|
302
|
+
/** Function to convert selected config values to spawn args (applied via process restart when config/* not supported) */
|
|
303
|
+
spawnArgBuilder?: (config: Record<string, string>) => string[];
|
|
304
|
+
/** ACP agent auth methods (multiple supported — in priority order) */
|
|
305
|
+
auth?: AcpAuthMethod[];
|
|
306
|
+
}
|
|
307
|
+
export interface ProviderResumeCapability {
|
|
308
|
+
supported: boolean;
|
|
309
|
+
stopStrategy?: 'command' | 'ctrl_c';
|
|
310
|
+
stopCommand?: string;
|
|
311
|
+
shutdownGraceMs?: number;
|
|
312
|
+
resumeArgs?: string[];
|
|
313
|
+
}
|
|
314
|
+
/** ACP auth method — based on ACP official spec */
|
|
315
|
+
export type AcpAuthMethod = AcpAuthEnvVar | AcpAuthAgent | AcpAuthTerminal;
|
|
316
|
+
/** Environment variable-based auth (API keys etc) */
|
|
317
|
+
export interface AcpAuthEnvVar {
|
|
318
|
+
type: 'env_var';
|
|
319
|
+
id: string;
|
|
320
|
+
name: string;
|
|
321
|
+
vars: Array<{
|
|
322
|
+
name: string;
|
|
323
|
+
label?: string;
|
|
324
|
+
secret?: boolean;
|
|
325
|
+
optional?: boolean;
|
|
326
|
+
}>;
|
|
327
|
+
link?: string;
|
|
328
|
+
}
|
|
329
|
+
/** Agent self-auth (OAuth, browser-based etc) */
|
|
330
|
+
export interface AcpAuthAgent {
|
|
331
|
+
type: 'agent';
|
|
332
|
+
id: string;
|
|
333
|
+
name: string;
|
|
334
|
+
description?: string;
|
|
335
|
+
}
|
|
336
|
+
/** Terminal command-based auth (runs setup command) */
|
|
337
|
+
export interface AcpAuthTerminal {
|
|
338
|
+
type: 'terminal';
|
|
339
|
+
id: string;
|
|
340
|
+
name: string;
|
|
341
|
+
description?: string;
|
|
342
|
+
args?: string[];
|
|
343
|
+
env?: Record<string, string>;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* CDP script functions.
|
|
347
|
+
* Each function takes a params object and returns a JS code string for CDP evaluate.
|
|
348
|
+
* The JS execution result must conform to the Output Contract.
|
|
349
|
+
*
|
|
350
|
+
* Custom scripts can be added via index signature in addition to built-in scripts.
|
|
351
|
+
* All scripts can receive params: Record<string, any>,
|
|
352
|
+
* backward compatible with legacy single-argument style (e.g. sendMessage(text)).
|
|
353
|
+
*/
|
|
354
|
+
export interface ProviderScripts {
|
|
355
|
+
readChat?: (params?: Record<string, any>) => string;
|
|
356
|
+
sendMessage?: (params?: Record<string, any>) => string;
|
|
357
|
+
listSessions?: (params?: Record<string, any>) => string;
|
|
358
|
+
switchSession?: (params?: Record<string, any>) => string;
|
|
359
|
+
newSession?: (params?: Record<string, any>) => string;
|
|
360
|
+
focusEditor?: (params?: Record<string, any>) => string;
|
|
361
|
+
openPanel?: (params?: Record<string, any>) => string;
|
|
362
|
+
/** List available models → { models: string[], current: string } */
|
|
363
|
+
listModels?: (params?: Record<string, any>) => string;
|
|
364
|
+
/** Change model → { success: boolean } */
|
|
365
|
+
setModel?: (params?: Record<string, any>) => string;
|
|
366
|
+
/** List available modes → { modes: string[], current: string } */
|
|
367
|
+
listModes?: (params?: Record<string, any>) => string;
|
|
368
|
+
/** Change mode → { success: boolean } */
|
|
369
|
+
setMode?: (params?: Record<string, any>) => string;
|
|
370
|
+
/** params: { action: 'approve'|'reject'|'custom', button?: string } */
|
|
371
|
+
resolveAction?: (params?: Record<string, any>) => string;
|
|
372
|
+
webviewResolveAction?: (params?: Record<string, any>) => string;
|
|
373
|
+
listNotifications?: (params?: Record<string, any>) => string;
|
|
374
|
+
dismissNotification?: (params?: Record<string, any>) => string;
|
|
375
|
+
[scriptName: string]: ((params?: Record<string, any>) => string) | undefined;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* ProviderLoader.resolve() result: Final provider with OS/version overrides applied
|
|
379
|
+
*/
|
|
380
|
+
export interface ResolvedProvider extends ProviderModule {
|
|
381
|
+
/** OS applied during resolve */
|
|
382
|
+
_resolvedOs?: string;
|
|
383
|
+
/** Version applied during resolve */
|
|
384
|
+
_resolvedVersion?: string;
|
|
385
|
+
/** Warning when detected version is not in compatibility matrix */
|
|
386
|
+
_versionWarning?: string;
|
|
387
|
+
}
|
|
388
|
+
/** Setting variable definition declared by provider */
|
|
389
|
+
export interface ProviderSettingDef {
|
|
390
|
+
type: 'boolean' | 'number' | 'string' | 'select';
|
|
391
|
+
default: any;
|
|
392
|
+
/** true = controllable from dashboard UI */
|
|
393
|
+
public: boolean;
|
|
394
|
+
/** UI label */
|
|
395
|
+
label?: string;
|
|
396
|
+
/** UI description */
|
|
397
|
+
description?: string;
|
|
398
|
+
/** Minimum value for number type */
|
|
399
|
+
min?: number;
|
|
400
|
+
/** Maximum value for number type */
|
|
401
|
+
max?: number;
|
|
402
|
+
/** Options for select type */
|
|
403
|
+
options?: string[];
|
|
404
|
+
}
|
|
405
|
+
/** Public settings schema (for dashboard transmission) */
|
|
406
|
+
export interface ProviderSettingSchema extends ProviderSettingDef {
|
|
407
|
+
key: string;
|
|
408
|
+
}
|
|
@@ -324,6 +324,7 @@ export interface ProviderModule {
|
|
|
324
324
|
ready?: RegExp[];
|
|
325
325
|
};
|
|
326
326
|
cleanOutput?: (raw: string, lastUserInput?: string) => string;
|
|
327
|
+
resume?: ProviderResumeCapability;
|
|
327
328
|
|
|
328
329
|
// ─── CDP scripts (ide/extension category) ───
|
|
329
330
|
scripts?: ProviderScripts;
|
|
@@ -388,6 +389,14 @@ export interface ProviderModule {
|
|
|
388
389
|
auth?: AcpAuthMethod[];
|
|
389
390
|
}
|
|
390
391
|
|
|
392
|
+
export interface ProviderResumeCapability {
|
|
393
|
+
supported: boolean;
|
|
394
|
+
stopStrategy?: 'command' | 'ctrl_c';
|
|
395
|
+
stopCommand?: string;
|
|
396
|
+
shutdownGraceMs?: number;
|
|
397
|
+
resumeArgs?: string[];
|
|
398
|
+
}
|
|
399
|
+
|
|
391
400
|
// ─── ACP Auth Types ─────────────────────────────────
|
|
392
401
|
|
|
393
402
|
/** ACP auth method — based on ACP official spec */
|
|
@@ -42,6 +42,27 @@ export class ProviderInstanceManager {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
removeByCategory(
|
|
46
|
+
category: 'cli' | 'ide' | 'extension' | 'acp',
|
|
47
|
+
options: { dispose?: boolean } = {},
|
|
48
|
+
): number {
|
|
49
|
+
const dispose = options.dispose !== false;
|
|
50
|
+
let removed = 0;
|
|
51
|
+
for (const [id, instance] of this.instances) {
|
|
52
|
+
if (instance.category !== category) continue;
|
|
53
|
+
if (dispose) {
|
|
54
|
+
try {
|
|
55
|
+
instance.dispose();
|
|
56
|
+
} catch {
|
|
57
|
+
// noop
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
this.instances.delete(id);
|
|
61
|
+
removed += 1;
|
|
62
|
+
}
|
|
63
|
+
return removed;
|
|
64
|
+
}
|
|
65
|
+
|
|
45
66
|
/**
|
|
46
67
|
* Import by Instance ID
|
|
47
68
|
*/
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProviderInstance — Provider runtime lifecycle
|
|
3
|
+
*
|
|
4
|
+
* provider.js = static config/scripts
|
|
5
|
+
* ProviderInstance = runtime status management + lifecycle
|
|
6
|
+
*
|
|
7
|
+
* Daemon only collects via ProviderInstance.getState(),
|
|
8
|
+
* Each Instance manages its own status.
|
|
9
|
+
*/
|
|
10
|
+
import type { ProviderResumeCapability } from './contracts.js';
|
|
11
|
+
import type { AcpConfigOption, AcpMode } from '../shared-types.js';
|
|
12
|
+
import type { ChatMessage } from '../types.js';
|
|
13
|
+
export type ProviderStatus = 'idle' | 'generating' | 'waiting_approval' | 'error' | 'stopped' | 'starting';
|
|
14
|
+
export interface ProviderRuntimeWriteOwner {
|
|
15
|
+
clientId: string;
|
|
16
|
+
ownerType: 'agent' | 'user';
|
|
17
|
+
}
|
|
18
|
+
export interface ProviderRuntimeClient {
|
|
19
|
+
clientId: string;
|
|
20
|
+
type: 'daemon' | 'web' | 'local-terminal';
|
|
21
|
+
readOnly: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface ProviderRuntimeInfo {
|
|
24
|
+
runtimeId: string;
|
|
25
|
+
runtimeKey?: string;
|
|
26
|
+
displayName?: string;
|
|
27
|
+
workspaceLabel?: string;
|
|
28
|
+
writeOwner?: ProviderRuntimeWriteOwner | null;
|
|
29
|
+
attachedClients?: ProviderRuntimeClient[];
|
|
30
|
+
}
|
|
31
|
+
export interface ActiveChatData {
|
|
32
|
+
id: string;
|
|
33
|
+
title: string;
|
|
34
|
+
status: string;
|
|
35
|
+
messages: ChatMessage[];
|
|
36
|
+
activeModal: {
|
|
37
|
+
message: string;
|
|
38
|
+
buttons: string[];
|
|
39
|
+
} | null;
|
|
40
|
+
terminalHistory?: string;
|
|
41
|
+
inputContent?: string;
|
|
42
|
+
}
|
|
43
|
+
/** Standardized error reasons across all provider categories */
|
|
44
|
+
export type ProviderErrorReason = 'not_installed' | 'auth_failed' | 'spawn_error' | 'init_failed' | 'crash' | 'timeout' | 'cdp_error' | 'disconnected';
|
|
45
|
+
/** Common fields shared by all provider categories */
|
|
46
|
+
interface ProviderStateBase {
|
|
47
|
+
/** Provider type (e.g. 'gemini-cli', 'cursor', 'cline') */
|
|
48
|
+
type: string;
|
|
49
|
+
/** Provider Display name */
|
|
50
|
+
name: string;
|
|
51
|
+
/** current status */
|
|
52
|
+
status: ProviderStatus;
|
|
53
|
+
/** chat data */
|
|
54
|
+
activeChat: ActiveChatData | null;
|
|
55
|
+
/** Workspace — project path or name (all categories) */
|
|
56
|
+
workspace?: string | null;
|
|
57
|
+
/** Runtime info (real-time detection) */
|
|
58
|
+
currentModel?: string;
|
|
59
|
+
currentPlan?: string;
|
|
60
|
+
/** Error details (when status === 'error') */
|
|
61
|
+
errorMessage?: string;
|
|
62
|
+
errorReason?: ProviderErrorReason;
|
|
63
|
+
/** meta */
|
|
64
|
+
instanceId: string;
|
|
65
|
+
lastUpdated: number;
|
|
66
|
+
settings: Record<string, any>;
|
|
67
|
+
/** Event queue (cleared after daemon collects) */
|
|
68
|
+
pendingEvents: ProviderEvent[];
|
|
69
|
+
runtime?: ProviderRuntimeInfo;
|
|
70
|
+
resume?: ProviderResumeCapability;
|
|
71
|
+
}
|
|
72
|
+
/** IDE provider state */
|
|
73
|
+
export interface IdeProviderState extends ProviderStateBase {
|
|
74
|
+
category: 'ide';
|
|
75
|
+
cdpConnected: boolean;
|
|
76
|
+
/** IDE child Extension Instance status */
|
|
77
|
+
extensions: ProviderState[];
|
|
78
|
+
currentAutoApprove?: string;
|
|
79
|
+
}
|
|
80
|
+
/** CLI provider state */
|
|
81
|
+
export interface CliProviderState extends ProviderStateBase {
|
|
82
|
+
category: 'cli';
|
|
83
|
+
/** terminal = PTY stream, chat = parsed conversation */
|
|
84
|
+
mode: 'terminal' | 'chat';
|
|
85
|
+
}
|
|
86
|
+
/** ACP provider state */
|
|
87
|
+
export interface AcpProviderState extends ProviderStateBase {
|
|
88
|
+
category: 'acp';
|
|
89
|
+
mode: 'chat';
|
|
90
|
+
/** ACP config options (model/mode selection) */
|
|
91
|
+
acpConfigOptions?: AcpConfigOption[];
|
|
92
|
+
/** ACP available modes */
|
|
93
|
+
acpModes?: AcpMode[];
|
|
94
|
+
}
|
|
95
|
+
/** Extension provider state */
|
|
96
|
+
export interface ExtensionProviderState extends ProviderStateBase {
|
|
97
|
+
category: 'extension';
|
|
98
|
+
agentStreams?: any[];
|
|
99
|
+
}
|
|
100
|
+
/** Discriminated union — switch on `.category` */
|
|
101
|
+
export type ProviderState = IdeProviderState | CliProviderState | AcpProviderState | ExtensionProviderState;
|
|
102
|
+
export interface ProviderEvent {
|
|
103
|
+
event: string;
|
|
104
|
+
timestamp: number;
|
|
105
|
+
[key: string]: any;
|
|
106
|
+
}
|
|
107
|
+
export interface InstanceContext {
|
|
108
|
+
/** CDP connection (IDE/Extension) */
|
|
109
|
+
cdp?: {
|
|
110
|
+
isConnected: boolean;
|
|
111
|
+
evaluate(script: string, timeout?: number): Promise<unknown>;
|
|
112
|
+
evaluateInWebviewFrame?(expression: string, matchFn?: (bodyPreview: string) => boolean): Promise<string | null>;
|
|
113
|
+
discoverAgentWebviews?(): Promise<any[]>;
|
|
114
|
+
};
|
|
115
|
+
/** Server log transmit */
|
|
116
|
+
serverConn?: {
|
|
117
|
+
sendMessage(type: string, data: any): void;
|
|
118
|
+
};
|
|
119
|
+
/** P2P PTY output transmit */
|
|
120
|
+
onPtyData?: (data: string) => void;
|
|
121
|
+
/** Provider configvalue (resolved) */
|
|
122
|
+
settings: Record<string, any>;
|
|
123
|
+
}
|
|
124
|
+
export interface ProviderInstance {
|
|
125
|
+
/** Provider type */
|
|
126
|
+
readonly type: string;
|
|
127
|
+
/** Provider category */
|
|
128
|
+
readonly category: 'cli' | 'ide' | 'extension' | 'acp';
|
|
129
|
+
/** initialize */
|
|
130
|
+
init(context: InstanceContext): Promise<void>;
|
|
131
|
+
/** Tick — periodic status refresh (IDE: readChat, Extension: stream collection) */
|
|
132
|
+
onTick(): Promise<void>;
|
|
133
|
+
/** Return current status */
|
|
134
|
+
getState(): ProviderState;
|
|
135
|
+
/** Receive event (external → Instance) */
|
|
136
|
+
onEvent(event: string, data?: any): void;
|
|
137
|
+
/** Update settings at runtime (called when user changes settings from dashboard) */
|
|
138
|
+
updateSettings?(newSettings: Record<string, any>): void;
|
|
139
|
+
/** cleanup */
|
|
140
|
+
dispose(): void;
|
|
141
|
+
}
|
|
142
|
+
export {};
|