@theia/ai-ide 1.64.0-next.0 → 1.64.0-next.17
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/lib/browser/ai-configuration/agent-configuration-widget.d.ts.map +1 -1
- package/lib/browser/ai-configuration/agent-configuration-widget.js +1 -1
- package/lib/browser/ai-configuration/agent-configuration-widget.js.map +1 -1
- package/lib/browser/ai-configuration/template-settings-renderer.d.ts +1 -2
- package/lib/browser/ai-configuration/template-settings-renderer.d.ts.map +1 -1
- package/lib/browser/ai-configuration/template-settings-renderer.js +5 -3
- package/lib/browser/ai-configuration/template-settings-renderer.js.map +1 -1
- package/lib/browser/app-tester-chat-agent.d.ts +1 -1
- package/lib/browser/app-tester-chat-agent.d.ts.map +1 -1
- package/lib/browser/app-tester-chat-agent.js +32 -10
- package/lib/browser/app-tester-chat-agent.js.map +1 -1
- package/lib/browser/app-tester-chat-functions.d.ts +25 -0
- package/lib/browser/app-tester-chat-functions.d.ts.map +1 -0
- package/lib/browser/app-tester-chat-functions.js +170 -0
- package/lib/browser/app-tester-chat-functions.js.map +1 -0
- package/lib/browser/frontend-module.d.ts.map +1 -1
- package/lib/browser/frontend-module.js +10 -0
- package/lib/browser/frontend-module.js.map +1 -1
- package/lib/common/app-tester-chat-functions.d.ts +5 -0
- package/lib/common/app-tester-chat-functions.d.ts.map +1 -0
- package/lib/common/app-tester-chat-functions.js +23 -0
- package/lib/common/app-tester-chat-functions.js.map +1 -0
- package/lib/common/browser-automation-protocol.d.ts +15 -0
- package/lib/common/browser-automation-protocol.d.ts.map +1 -0
- package/lib/common/browser-automation-protocol.js +22 -0
- package/lib/common/browser-automation-protocol.js.map +1 -0
- package/lib/node/app-tester-agent/browser-automation-impl.d.ts +18 -0
- package/lib/node/app-tester-agent/browser-automation-impl.d.ts.map +1 -0
- package/lib/node/app-tester-agent/browser-automation-impl.js +96 -0
- package/lib/node/app-tester-agent/browser-automation-impl.js.map +1 -0
- package/lib/node/backend-module.d.ts +4 -0
- package/lib/node/backend-module.d.ts.map +1 -0
- package/lib/node/backend-module.js +35 -0
- package/lib/node/backend-module.js.map +1 -0
- package/package.json +21 -19
- package/src/browser/ai-configuration/agent-configuration-widget.tsx +0 -1
- package/src/browser/ai-configuration/template-settings-renderer.tsx +5 -5
- package/src/browser/app-tester-chat-agent.ts +135 -111
- package/src/browser/app-tester-chat-functions.ts +170 -0
- package/src/browser/frontend-module.ts +19 -1
- package/src/common/app-tester-chat-functions.ts +20 -0
- package/src/common/browser-automation-protocol.ts +32 -0
- package/src/node/app-tester-agent/browser-automation-impl.ts +107 -0
- package/src/node/backend-module.ts +38 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 EclipseSource GmbH.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
import { type ToolProvider, type ToolRequest } from '@theia/ai-core';
|
|
17
|
+
import { isLocalMCPServerDescription, MCPServerManager } from '@theia/ai-mcp/lib/common';
|
|
18
|
+
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
19
|
+
import { CLOSE_BROWSER_FUNCTION_ID, IS_BROWSER_RUNNING_FUNCTION_ID, LAUNCH_BROWSER_FUNCTION_ID, QUERY_DOM_FUNCTION_ID } from '../common/app-tester-chat-functions';
|
|
20
|
+
import { BrowserAutomation } from '../common/browser-automation-protocol';
|
|
21
|
+
|
|
22
|
+
@injectable()
|
|
23
|
+
export abstract class BrowserAutomationToolProvider implements ToolProvider {
|
|
24
|
+
@inject(BrowserAutomation)
|
|
25
|
+
protected readonly browser: BrowserAutomation;
|
|
26
|
+
|
|
27
|
+
abstract getTool(): ToolRequest;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@injectable()
|
|
31
|
+
export class LaunchBrowserProvider extends BrowserAutomationToolProvider {
|
|
32
|
+
static ID = LAUNCH_BROWSER_FUNCTION_ID;
|
|
33
|
+
|
|
34
|
+
@inject(MCPServerManager)
|
|
35
|
+
protected readonly mcpServerManager: MCPServerManager;
|
|
36
|
+
|
|
37
|
+
getTool(): ToolRequest {
|
|
38
|
+
return {
|
|
39
|
+
id: LaunchBrowserProvider.ID,
|
|
40
|
+
name: LaunchBrowserProvider.ID,
|
|
41
|
+
description: 'Start the browser.',
|
|
42
|
+
parameters: {
|
|
43
|
+
type: 'object',
|
|
44
|
+
properties: {},
|
|
45
|
+
required: []
|
|
46
|
+
}, handler: async () => {
|
|
47
|
+
try {
|
|
48
|
+
|
|
49
|
+
const mcp = await this.mcpServerManager.getServerDescription('playwright');
|
|
50
|
+
if (!mcp) {
|
|
51
|
+
throw new Error('No MCP Playwright instance with name playwright found');
|
|
52
|
+
}
|
|
53
|
+
if (!isLocalMCPServerDescription(mcp)) {
|
|
54
|
+
throw new Error('The MCP Playwright instance must run locally.');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const cdpEndpointIndex = mcp.args?.findIndex(p => p === '--cdp-endpoint');
|
|
58
|
+
if (!cdpEndpointIndex) {
|
|
59
|
+
throw new Error('No --cdp-endpoint was provided.');
|
|
60
|
+
}
|
|
61
|
+
const cdpEndpoint = mcp.args?.[cdpEndpointIndex + 1];
|
|
62
|
+
if (!cdpEndpoint) {
|
|
63
|
+
throw new Error('No --cdp-endpoint argument was provided.');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let remoteDebuggingPort = 9222;
|
|
67
|
+
try {
|
|
68
|
+
const uri = new URL(cdpEndpoint);
|
|
69
|
+
if (uri.port) {
|
|
70
|
+
remoteDebuggingPort = parseInt(uri.port, 10);
|
|
71
|
+
} else {
|
|
72
|
+
// Default ports if not specified
|
|
73
|
+
remoteDebuggingPort = uri.protocol === 'https:' ? 443 : 80;
|
|
74
|
+
}
|
|
75
|
+
} catch (error) {
|
|
76
|
+
throw new Error(`Invalid --cdp-endpoint format, URL expected: ${cdpEndpoint}`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const result = await this.browser.launch(remoteDebuggingPort);
|
|
80
|
+
return result;
|
|
81
|
+
} catch (ex) {
|
|
82
|
+
return (`Failed to starting the browser: ${ex.message}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@injectable()
|
|
90
|
+
export class CloseBrowserProvider extends BrowserAutomationToolProvider {
|
|
91
|
+
static ID = CLOSE_BROWSER_FUNCTION_ID;
|
|
92
|
+
|
|
93
|
+
getTool(): ToolRequest {
|
|
94
|
+
return {
|
|
95
|
+
id: CloseBrowserProvider.ID,
|
|
96
|
+
name: CloseBrowserProvider.ID,
|
|
97
|
+
description: 'Close the browser.',
|
|
98
|
+
parameters: {
|
|
99
|
+
type: 'object',
|
|
100
|
+
properties: {},
|
|
101
|
+
required: []
|
|
102
|
+
},
|
|
103
|
+
handler: async () => {
|
|
104
|
+
try {
|
|
105
|
+
await this.browser.close();
|
|
106
|
+
} catch (ex) {
|
|
107
|
+
return (`Failed to close browser: ${ex.message}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@injectable()
|
|
115
|
+
export class IsBrowserRunningProvider extends BrowserAutomationToolProvider {
|
|
116
|
+
static ID = IS_BROWSER_RUNNING_FUNCTION_ID;
|
|
117
|
+
|
|
118
|
+
getTool(): ToolRequest {
|
|
119
|
+
return {
|
|
120
|
+
id: IsBrowserRunningProvider.ID,
|
|
121
|
+
name: IsBrowserRunningProvider.ID,
|
|
122
|
+
description: 'Check if the browser is running.',
|
|
123
|
+
parameters: {
|
|
124
|
+
type: 'object',
|
|
125
|
+
properties: {},
|
|
126
|
+
required: []
|
|
127
|
+
},
|
|
128
|
+
handler: async () => {
|
|
129
|
+
try {
|
|
130
|
+
const isRunning = await this.browser.isRunning();
|
|
131
|
+
return isRunning ? 'Browser is running.' : 'Browser is not running.';
|
|
132
|
+
} catch (ex) {
|
|
133
|
+
return (`Failed to check if browser is running: ${ex.message}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@injectable()
|
|
141
|
+
export class QueryDomProvider extends BrowserAutomationToolProvider {
|
|
142
|
+
static ID = QUERY_DOM_FUNCTION_ID;
|
|
143
|
+
|
|
144
|
+
getTool(): ToolRequest {
|
|
145
|
+
return {
|
|
146
|
+
id: QueryDomProvider.ID,
|
|
147
|
+
name: QueryDomProvider.ID,
|
|
148
|
+
description: 'Query the DOM of the active page.',
|
|
149
|
+
parameters: {
|
|
150
|
+
type: 'object',
|
|
151
|
+
properties: {
|
|
152
|
+
selector: {
|
|
153
|
+
type: 'string',
|
|
154
|
+
description: `The selector of the element to get the DOM of. The selector is a
|
|
155
|
+
CSS selector that identifies the element. If not provided, the entire DOM will be returned.`
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
required: []
|
|
159
|
+
},
|
|
160
|
+
handler: async arg => {
|
|
161
|
+
try {
|
|
162
|
+
const { selector } = JSON.parse(arg);
|
|
163
|
+
return await this.browser.queryDom(selector);
|
|
164
|
+
} catch (ex) {
|
|
165
|
+
return (`Failed to get DOM: ${ex.message}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -24,7 +24,14 @@ import { CoderAgent } from './coder-agent';
|
|
|
24
24
|
import { SummarizeSessionCommandContribution } from './summarize-session-command-contribution';
|
|
25
25
|
import { FileContentFunction, FileDiagnosticProvider, GetWorkspaceDirectoryStructure, GetWorkspaceFileList, WorkspaceFunctionScope } from './workspace-functions';
|
|
26
26
|
import { WorkspaceSearchProvider } from './workspace-search-provider';
|
|
27
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
FrontendApplicationContribution,
|
|
29
|
+
PreferenceContribution,
|
|
30
|
+
WidgetFactory,
|
|
31
|
+
bindViewContribution,
|
|
32
|
+
RemoteConnectionProvider,
|
|
33
|
+
ServiceConnectionProvider
|
|
34
|
+
} from '@theia/core/lib/browser';
|
|
28
35
|
import { TaskListProvider, TaskRunnerProvider } from './workspace-task-provider';
|
|
29
36
|
import { WorkspacePreferencesSchema } from './workspace-preferences';
|
|
30
37
|
import {
|
|
@@ -62,6 +69,8 @@ import { TaskContextFileStorageService } from './task-context-file-storage-servi
|
|
|
62
69
|
import { TaskContextStorageService } from '@theia/ai-chat/lib/browser/task-context-service';
|
|
63
70
|
import { CommandContribution } from '@theia/core';
|
|
64
71
|
import { AIPromptFragmentsConfigurationWidget } from './ai-configuration/prompt-fragments-configuration-widget';
|
|
72
|
+
import { BrowserAutomation, browserAutomationPath } from '../common/browser-automation-protocol';
|
|
73
|
+
import { CloseBrowserProvider, IsBrowserRunningProvider, LaunchBrowserProvider, QueryDomProvider } from './app-tester-chat-functions';
|
|
65
74
|
|
|
66
75
|
export default new ContainerModule((bind, _unbind, _isBound, rebind) => {
|
|
67
76
|
bind(PreferenceContribution).toConstantValue({ schema: WorkspacePreferencesSchema });
|
|
@@ -85,6 +94,10 @@ export default new ContainerModule((bind, _unbind, _isBound, rebind) => {
|
|
|
85
94
|
bind(AppTesterChatAgent).toSelf().inSingletonScope();
|
|
86
95
|
bind(Agent).toService(AppTesterChatAgent);
|
|
87
96
|
bind(ChatAgent).toService(AppTesterChatAgent);
|
|
97
|
+
bind(BrowserAutomation).toDynamicValue(ctx => {
|
|
98
|
+
const provider = ctx.container.get<ServiceConnectionProvider>(RemoteConnectionProvider);
|
|
99
|
+
return provider.createProxy<BrowserAutomation>(browserAutomationPath);
|
|
100
|
+
}).inSingletonScope();
|
|
88
101
|
|
|
89
102
|
bind(CommandChatAgent).toSelf().inSingletonScope();
|
|
90
103
|
bind(Agent).toService(CommandChatAgent);
|
|
@@ -120,6 +133,11 @@ export default new ContainerModule((bind, _unbind, _isBound, rebind) => {
|
|
|
120
133
|
}))
|
|
121
134
|
.inSingletonScope();
|
|
122
135
|
|
|
136
|
+
bindToolProvider(LaunchBrowserProvider, bind);
|
|
137
|
+
bindToolProvider(CloseBrowserProvider, bind);
|
|
138
|
+
bindToolProvider(IsBrowserRunningProvider, bind);
|
|
139
|
+
bindToolProvider(QueryDomProvider, bind);
|
|
140
|
+
|
|
123
141
|
bindViewContribution(bind, AIAgentConfigurationViewContribution);
|
|
124
142
|
bind(TabBarToolbarContribution).toService(AIAgentConfigurationViewContribution);
|
|
125
143
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 EclipseSource GmbH.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
export const LAUNCH_BROWSER_FUNCTION_ID = 'launchBrowser';
|
|
18
|
+
export const IS_BROWSER_RUNNING_FUNCTION_ID = 'isBrowserRunning';
|
|
19
|
+
export const CLOSE_BROWSER_FUNCTION_ID = 'closeBrowser';
|
|
20
|
+
export const QUERY_DOM_FUNCTION_ID = 'queryDom';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 EclipseSource GmbH.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
export const browserAutomationPath = '/services/automation/browser';
|
|
18
|
+
export const BrowserAutomation = Symbol('BrowserAutomation');
|
|
19
|
+
export interface BrowserAutomation {
|
|
20
|
+
launch(remoteDebuggingPort: number): Promise<LaunchResult | undefined>;
|
|
21
|
+
isRunning(): Promise<boolean>;
|
|
22
|
+
queryDom(selector?: string): Promise<string>;
|
|
23
|
+
close(): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface LaunchResult {
|
|
27
|
+
remoteDebuggingPort: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const BrowserAutomationClient = Symbol('BrowserAutomationClient');
|
|
31
|
+
export interface BrowserAutomationClient {
|
|
32
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 EclipseSource GmbH.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { type RpcServer } from '@theia/core';
|
|
18
|
+
import { injectable } from '@theia/core/shared/inversify';
|
|
19
|
+
import { Browser, launch, Page } from 'puppeteer-core';
|
|
20
|
+
import type { BrowserAutomation, BrowserAutomationClient, LaunchResult } from '../../common/browser-automation-protocol';
|
|
21
|
+
|
|
22
|
+
const MAX_DOM_LENGTH = 50000;
|
|
23
|
+
|
|
24
|
+
@injectable()
|
|
25
|
+
export class BrowserAutomationImpl implements RpcServer<BrowserAutomationClient>, BrowserAutomation {
|
|
26
|
+
protected _browser?: Browser;
|
|
27
|
+
protected _page?: Page;
|
|
28
|
+
protected client?: BrowserAutomationClient;
|
|
29
|
+
|
|
30
|
+
protected get browser(): Browser {
|
|
31
|
+
if (!this._browser) {
|
|
32
|
+
throw new Error('Browser is not launched');
|
|
33
|
+
}
|
|
34
|
+
return this._browser;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
protected get page(): Page {
|
|
38
|
+
if (!this._page) {
|
|
39
|
+
throw new Error('Page is not created');
|
|
40
|
+
}
|
|
41
|
+
return this._page;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async isRunning(): Promise<boolean> {
|
|
45
|
+
return this._browser !== undefined && this._browser.connected;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async launch(remoteDebuggingPort: number): Promise<LaunchResult | undefined> {
|
|
49
|
+
if (this._browser) {
|
|
50
|
+
await this.close();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const browser = await launch({
|
|
54
|
+
headless: false,
|
|
55
|
+
channel: 'chrome',
|
|
56
|
+
args: [
|
|
57
|
+
`--remote-debugging-port=${remoteDebuggingPort}`
|
|
58
|
+
],
|
|
59
|
+
});
|
|
60
|
+
this._browser = browser;
|
|
61
|
+
// The initial page will be used per default
|
|
62
|
+
this._page = (await browser.pages())[0];
|
|
63
|
+
return {
|
|
64
|
+
remoteDebuggingPort
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async close(): Promise<void> {
|
|
69
|
+
await this._browser?.close();
|
|
70
|
+
this._browser = undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async queryDom(selector?: string): Promise<string> {
|
|
74
|
+
const page = this.page;
|
|
75
|
+
let content = '';
|
|
76
|
+
|
|
77
|
+
if (selector) {
|
|
78
|
+
const element = await page.$(selector);
|
|
79
|
+
if (!element) {
|
|
80
|
+
throw new Error(`Element with selector "${selector}" not found`);
|
|
81
|
+
}
|
|
82
|
+
content = await page.evaluate(el => el.outerHTML, element);
|
|
83
|
+
} else {
|
|
84
|
+
content = await page.content();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (content.length > MAX_DOM_LENGTH) {
|
|
88
|
+
return 'The queried DOM is too large. Please provide a more specific query.';
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return content;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
dispose(): void {
|
|
95
|
+
this._browser?.close();
|
|
96
|
+
this._browser = undefined;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
setClient(client: BrowserAutomationClient | undefined): void {
|
|
100
|
+
this.client = client;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
getClient?(): BrowserAutomationClient | undefined {
|
|
104
|
+
return this.client;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2025 EclipseSource GmbH.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { ConnectionHandler, RpcConnectionHandler } from '@theia/core';
|
|
18
|
+
import { ContainerModule } from '@theia/core/shared/inversify';
|
|
19
|
+
import { BrowserAutomation, browserAutomationPath, type BrowserAutomationClient } from '../common/browser-automation-protocol';
|
|
20
|
+
import { BrowserAutomationImpl } from './app-tester-agent/browser-automation-impl';
|
|
21
|
+
import { ConnectionContainerModule } from '@theia/core/lib/node/messaging/connection-container-module';
|
|
22
|
+
|
|
23
|
+
const browserAutomationModule = ConnectionContainerModule.create(({ bind, bindBackendService, bindFrontendService }) => {
|
|
24
|
+
bind(BrowserAutomation).to(BrowserAutomationImpl).inSingletonScope();
|
|
25
|
+
bind(ConnectionHandler).toDynamicValue(ctx =>
|
|
26
|
+
new RpcConnectionHandler<BrowserAutomationClient>(browserAutomationPath, client => {
|
|
27
|
+
const server = ctx.container.get<BrowserAutomationImpl>(BrowserAutomation);
|
|
28
|
+
server.setClient(client);
|
|
29
|
+
client.onDidCloseConnection(() => server.close());
|
|
30
|
+
return server;
|
|
31
|
+
})
|
|
32
|
+
).inSingletonScope();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export default new ContainerModule(bind => {
|
|
36
|
+
bind(ConnectionContainerModule).toConstantValue(browserAutomationModule);
|
|
37
|
+
|
|
38
|
+
});
|