@narumitw/pi-chrome-devtools 0.53.2 → 0.53.4
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/README.md +1 -0
- package/dist/chunks/{browser-settings-menu-IMB6HXSU.js → browser-settings-menu-FVMCCUPM.ts} +16 -42
- package/dist/chunks/browser-settings-menu-FVMCCUPM.ts.map +7 -0
- package/dist/chunks/{chunk-GTTYS5GT.js → chunk-4B3EQHOH.ts} +2 -2
- package/dist/chunks/chunk-4B3EQHOH.ts.map +7 -0
- package/dist/chunks/{chunk-SRT3UUIP.js → chunk-LSJSDY2M.ts} +23 -74
- package/dist/chunks/chunk-LSJSDY2M.ts.map +7 -0
- package/dist/chunks/{chunk-LLXOCRNF.js → chunk-V7N3WI5B.ts} +12 -33
- package/dist/chunks/chunk-V7N3WI5B.ts.map +7 -0
- package/dist/chunks/{menu-UJETYMSB.js → menu-MTPSLDHZ.ts} +10 -23
- package/dist/chunks/menu-MTPSLDHZ.ts.map +7 -0
- package/dist/chunks/{tools-6P7EUX37.js → tools-OVNH45IJ.ts} +17 -59
- package/dist/chunks/tools-OVNH45IJ.ts.map +7 -0
- package/dist/index.ts +18 -42
- package/dist/index.ts.map +2 -2
- package/package.json +54 -55
- package/src/browser-manager.ts +872 -942
- package/src/browser-settings-menu.ts +315 -350
- package/src/cdp-client.ts +381 -398
- package/src/chrome-devtools.ts +205 -232
- package/src/display.ts +26 -29
- package/src/lazy-tools.ts +158 -181
- package/src/menu.ts +409 -446
- package/src/render.ts +72 -81
- package/src/runtime.ts +137 -140
- package/src/screenshot.ts +170 -186
- package/src/settings.ts +472 -523
- package/src/tool-names.ts +8 -14
- package/src/tool-selector.ts +242 -271
- package/src/tools.ts +218 -226
- package/src/webmcp/discovery.ts +184 -188
- package/src/webmcp/policy.ts +296 -329
- package/src/webmcp/protocol.ts +324 -337
- package/src/webmcp/tools.ts +136 -147
- package/dist/chunks/browser-settings-menu-IMB6HXSU.js.map +0 -7
- package/dist/chunks/chunk-GTTYS5GT.js.map +0 -7
- package/dist/chunks/chunk-LLXOCRNF.js.map +0 -7
- package/dist/chunks/chunk-SRT3UUIP.js.map +0 -7
- package/dist/chunks/menu-UJETYMSB.js.map +0 -7
- package/dist/chunks/tools-6P7EUX37.js.map +0 -7
package/src/render.ts
CHANGED
|
@@ -4,117 +4,108 @@ import { sanitizeChromeDevtoolsDisplay } from "./display.js";
|
|
|
4
4
|
|
|
5
5
|
const STATUS_KEY = "chrome-devtools";
|
|
6
6
|
interface StatusContext {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
sessionManager: object;
|
|
8
|
+
ui: { setStatus: (key: string, value: string | undefined) => void };
|
|
9
9
|
}
|
|
10
10
|
interface RenderTheme {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
bold(text: string): string;
|
|
12
|
+
fg(color: string, text: string): string;
|
|
13
13
|
}
|
|
14
14
|
const activeStatuses = new WeakMap<object, Array<{ status: string; token: symbol }>>();
|
|
15
15
|
|
|
16
16
|
interface RenderComponent {
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
invalidate(): void;
|
|
18
|
+
render(width: number): string[];
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export function renderToolCall(action: string) {
|
|
22
|
-
|
|
22
|
+
return () => new PiTextComponent(`Chrome DevTools: ${action}`);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export function renderTextResult(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
result: AgentToolResult<unknown>,
|
|
27
|
+
options: ToolRenderResultOptions,
|
|
28
|
+
theme: RenderTheme,
|
|
29
29
|
) {
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
const output = formatCollapsibleOutput(textContent(result), options);
|
|
31
|
+
return new PiTextComponent(output.text, theme, output.color);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export function renderScreenshotResult(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
result: AgentToolResult<unknown>,
|
|
36
|
+
options: ToolRenderResultOptions,
|
|
37
|
+
theme: RenderTheme,
|
|
38
38
|
): RenderComponent {
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
const output = formatCollapsibleOutput(screenshotTextContent(result), options);
|
|
40
|
+
return new PiTextComponent(output.text, theme, output.color);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
function textContent(result: AgentToolResult<unknown>) {
|
|
44
|
-
|
|
45
|
-
.flatMap((content) => (content.type === "text" ? [content.text] : []))
|
|
46
|
-
.join("\n");
|
|
44
|
+
return result.content.flatMap((content) => (content.type === "text" ? [content.text] : [])).join("\n");
|
|
47
45
|
}
|
|
48
46
|
|
|
49
47
|
function screenshotTextContent(result: AgentToolResult<unknown>) {
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
const text = textContent(result);
|
|
49
|
+
if (text.trim()) return text;
|
|
52
50
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
const details = result.details as { savedPath?: unknown; bytes?: unknown } | undefined;
|
|
52
|
+
if (typeof details?.savedPath !== "string") return text;
|
|
53
|
+
const bytes = typeof details.bytes === "number" ? ` (${details.bytes} bytes)` : "";
|
|
54
|
+
return `Saved screenshot to ${details.savedPath}${bytes}`;
|
|
57
55
|
}
|
|
58
56
|
|
|
59
|
-
function formatCollapsibleOutput(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
): { text: string; color?: string } {
|
|
63
|
-
if (options.isPartial) return { text: "Running...", color: "warning" };
|
|
64
|
-
if (options.expanded) return { text, color: "toolOutput" };
|
|
57
|
+
function formatCollapsibleOutput(text: string, options: ToolRenderResultOptions): { text: string; color?: string } {
|
|
58
|
+
if (options.isPartial) return { text: "Running...", color: "warning" };
|
|
59
|
+
if (options.expanded) return { text, color: "toolOutput" };
|
|
65
60
|
|
|
66
|
-
|
|
61
|
+
return { text: "" };
|
|
67
62
|
}
|
|
68
63
|
|
|
69
64
|
class PiTextComponent implements RenderComponent {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
65
|
+
private text: string;
|
|
66
|
+
private readonly theme?: RenderTheme;
|
|
67
|
+
private readonly color?: string;
|
|
68
|
+
|
|
69
|
+
constructor(text = "", theme?: RenderTheme, color?: string) {
|
|
70
|
+
this.text = text;
|
|
71
|
+
this.theme = theme;
|
|
72
|
+
this.color = color;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
setText(text: string) {
|
|
76
|
+
this.text = text;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
invalidate() {
|
|
80
|
+
// Stateless renderer: no cached layout to invalidate.
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
render(width: number) {
|
|
84
|
+
const sanitizedText = sanitizeChromeDevtoolsDisplay(this.text);
|
|
85
|
+
if (!sanitizedText.trim()) return [];
|
|
86
|
+
return sanitizedText
|
|
87
|
+
.replace(/\t/g, " ")
|
|
88
|
+
.split(/\r?\n/)
|
|
89
|
+
.map((line) => {
|
|
90
|
+
const truncatedLine = truncateToWidth(line, Math.max(0, width), "");
|
|
91
|
+
return this.theme && this.color ? this.theme.fg(this.color, truncatedLine) : truncatedLine;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
99
94
|
}
|
|
100
95
|
|
|
101
|
-
export async function withStatus<T>(
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const remaining = statuses.at(-1)?.status;
|
|
117
|
-
if (statuses.length === 0) activeStatuses.delete(ctx.sessionManager);
|
|
118
|
-
ctx.ui.setStatus(STATUS_KEY, remaining);
|
|
119
|
-
}
|
|
96
|
+
export async function withStatus<T>(ctx: StatusContext, status: string, callback: () => Promise<T>) {
|
|
97
|
+
const token = Symbol(status);
|
|
98
|
+
const statuses = activeStatuses.get(ctx.sessionManager) ?? [];
|
|
99
|
+
statuses.push({ status, token });
|
|
100
|
+
activeStatuses.set(ctx.sessionManager, statuses);
|
|
101
|
+
ctx.ui.setStatus(STATUS_KEY, status);
|
|
102
|
+
try {
|
|
103
|
+
return await callback();
|
|
104
|
+
} finally {
|
|
105
|
+
const index = statuses.findIndex((entry) => entry.token === token);
|
|
106
|
+
if (index >= 0) statuses.splice(index, 1);
|
|
107
|
+
const remaining = statuses.at(-1)?.status;
|
|
108
|
+
if (statuses.length === 0) activeStatuses.delete(ctx.sessionManager);
|
|
109
|
+
ctx.ui.setStatus(STATUS_KEY, remaining);
|
|
110
|
+
}
|
|
120
111
|
}
|
package/src/runtime.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { ChildProcess } from "node:child_process";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
DEFAULT_BROWSER_HOST,
|
|
4
|
+
DEFAULT_BROWSER_PORT,
|
|
5
|
+
type EffectiveBrowserSettings,
|
|
6
|
+
parseConfiguredPort,
|
|
7
7
|
} from "./settings.js";
|
|
8
8
|
|
|
9
9
|
export const DEFAULT_HOST = DEFAULT_BROWSER_HOST;
|
|
@@ -17,197 +17,194 @@ export const DEVTOOLS_ACTIVE_PORT_FILE = "DevToolsActivePort";
|
|
|
17
17
|
export const BROWSER_SHUTDOWN_WAIT_MS = 1_500;
|
|
18
18
|
|
|
19
19
|
export interface DevToolsPage {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
id: string;
|
|
21
|
+
type: string;
|
|
22
|
+
title: string;
|
|
23
|
+
url: string;
|
|
24
|
+
webSocketDebuggerUrl?: string;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export interface ChromeDevToolsState {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
28
|
+
host: string;
|
|
29
|
+
port: number;
|
|
30
|
+
configuredPort: number;
|
|
31
|
+
hostConfigured: boolean;
|
|
32
|
+
portConfigured: boolean;
|
|
33
|
+
autoLaunchEnabled: boolean;
|
|
34
|
+
endpointSource: EffectiveBrowserSettings["endpointSource"];
|
|
35
|
+
autoLaunchSource: EffectiveBrowserSettings["autoLaunchSource"];
|
|
36
|
+
browserExecutable?: string;
|
|
37
|
+
extensionPaths: string[];
|
|
38
|
+
browserExecutableSource: EffectiveBrowserSettings["executablePathSource"];
|
|
39
|
+
extensionPathsSource: EffectiveBrowserSettings["extensionPathsSource"];
|
|
40
|
+
settingsFilePath?: string;
|
|
41
|
+
projectSettingsFilePath?: string;
|
|
42
|
+
projectSettingsTrusted: boolean;
|
|
43
|
+
activePageId?: string;
|
|
44
|
+
managedBrowser?: ManagedBrowser;
|
|
45
|
+
launchPromise?: Promise<void>;
|
|
46
|
+
lastLaunchAttempt?: BrowserLaunchAttempt;
|
|
47
|
+
shuttingDown: boolean;
|
|
48
|
+
sessionGeneration: number;
|
|
49
|
+
sessionController: AbortController;
|
|
50
|
+
settingsNotice?: string;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export interface ManagedBrowser {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
54
|
+
process: ChildProcess;
|
|
55
|
+
userDataDir: string;
|
|
56
|
+
port?: number;
|
|
57
|
+
exited: boolean;
|
|
58
|
+
ready: boolean;
|
|
59
|
+
ownerGeneration: number;
|
|
60
|
+
sessionOwner?: object;
|
|
61
|
+
cleanupPromise?: Promise<void>;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
export interface BrowserLaunchAttempt {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
candidateLabels: string[];
|
|
66
|
+
mode: "dynamic-port" | "explicit-port";
|
|
67
|
+
selectedCandidate?: string;
|
|
68
|
+
userDataDir?: string;
|
|
69
|
+
lastError?: string;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
export interface BrowserCandidateDefinition {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
label: string;
|
|
74
|
+
executable: string;
|
|
75
|
+
source: "env" | "path" | "wellKnownPath";
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
export interface BrowserCandidate extends BrowserCandidateDefinition {
|
|
79
|
-
|
|
79
|
+
resolvedExecutable: string;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
export { parseConfiguredPort };
|
|
83
83
|
|
|
84
84
|
export const state: ChromeDevToolsState = {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
85
|
+
host: DEFAULT_HOST,
|
|
86
|
+
port: DEFAULT_PORT,
|
|
87
|
+
configuredPort: DEFAULT_PORT,
|
|
88
|
+
hostConfigured: false,
|
|
89
|
+
portConfigured: false,
|
|
90
|
+
autoLaunchEnabled: true,
|
|
91
|
+
endpointSource: "default",
|
|
92
|
+
autoLaunchSource: "default",
|
|
93
|
+
extensionPaths: [],
|
|
94
|
+
browserExecutableSource: "default",
|
|
95
|
+
extensionPathsSource: "default",
|
|
96
|
+
projectSettingsTrusted: false,
|
|
97
|
+
shuttingDown: false,
|
|
98
|
+
sessionGeneration: 0,
|
|
99
|
+
sessionController: new AbortController(),
|
|
100
100
|
};
|
|
101
101
|
|
|
102
102
|
interface WebMcpSessionRuntime {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
controller: AbortController;
|
|
104
|
+
enabled: boolean;
|
|
105
|
+
controllers: Set<AbortController>;
|
|
106
|
+
generation: number;
|
|
107
|
+
sessionGeneration: number;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
const webMcpRuntimeByOwner = new WeakMap<object, WebMcpSessionRuntime>();
|
|
111
111
|
|
|
112
112
|
export function setWebMcpSessionOwner(owner: object) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
113
|
+
const runtime = webMcpRuntime(owner);
|
|
114
|
+
runtime.enabled = false;
|
|
115
|
+
runtime.sessionGeneration += 1;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
export function beginWebMcpOperation(owner: object, toolSignal?: AbortSignal) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
119
|
+
const runtime = webMcpRuntime(owner);
|
|
120
|
+
const controller = new AbortController();
|
|
121
|
+
runtime.controllers.add(controller);
|
|
122
|
+
const signals = [controller.signal, runtime.controller.signal];
|
|
123
|
+
if (toolSignal) signals.push(toolSignal);
|
|
124
|
+
const signal = AbortSignal.any(signals);
|
|
125
|
+
return {
|
|
126
|
+
signal,
|
|
127
|
+
owner,
|
|
128
|
+
sessionGeneration: runtime.sessionGeneration,
|
|
129
|
+
webMcpGeneration: runtime.generation,
|
|
130
|
+
dispose() {
|
|
131
|
+
runtime.controllers.delete(controller);
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
export function invalidateWebMcpOperations(owner: object, reason: string) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
137
|
+
const runtime = webMcpRuntime(owner);
|
|
138
|
+
runtime.generation += 1;
|
|
139
|
+
const controllers = [...runtime.controllers];
|
|
140
|
+
runtime.controllers.clear();
|
|
141
|
+
const error = new DOMException(reason, "AbortError");
|
|
142
|
+
runtime.controller.abort(error);
|
|
143
|
+
runtime.controller = new AbortController();
|
|
144
|
+
for (const controller of controllers) controller.abort(error);
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
export function currentWebMcpGeneration(owner: object) {
|
|
148
|
-
|
|
148
|
+
return webMcpRuntime(owner).generation;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
export function webMcpSessionSignal(owner: object) {
|
|
152
|
-
|
|
152
|
+
return webMcpRuntime(owner).controller.signal;
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
export function applyRuntimeWebMcpSetting(enabled: boolean, owner: object) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
156
|
+
const runtime = webMcpRuntime(owner);
|
|
157
|
+
if (runtime.enabled !== enabled) {
|
|
158
|
+
invalidateWebMcpOperations(owner, `WebMCP ${enabled ? "enabled" : "disabled"}`);
|
|
159
|
+
}
|
|
160
|
+
runtime.enabled = enabled;
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
export function webMcpEnabled(owner: object) {
|
|
164
|
-
|
|
164
|
+
return webMcpRuntime(owner).enabled;
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
export function webMcpOperationIsCurrent(operation: {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
168
|
+
owner: object;
|
|
169
|
+
sessionGeneration: number;
|
|
170
|
+
webMcpGeneration: number;
|
|
171
171
|
}) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
operation.sessionGeneration === runtime.sessionGeneration &&
|
|
175
|
-
operation.webMcpGeneration === runtime.generation
|
|
176
|
-
);
|
|
172
|
+
const runtime = webMcpRuntime(operation.owner);
|
|
173
|
+
return operation.sessionGeneration === runtime.sessionGeneration && operation.webMcpGeneration === runtime.generation;
|
|
177
174
|
}
|
|
178
175
|
|
|
179
176
|
function webMcpRuntime(owner: object) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
177
|
+
const existing = webMcpRuntimeByOwner.get(owner);
|
|
178
|
+
if (existing) return existing;
|
|
179
|
+
const created: WebMcpSessionRuntime = {
|
|
180
|
+
controller: new AbortController(),
|
|
181
|
+
controllers: new Set(),
|
|
182
|
+
enabled: false,
|
|
183
|
+
generation: 0,
|
|
184
|
+
sessionGeneration: 0,
|
|
185
|
+
};
|
|
186
|
+
webMcpRuntimeByOwner.set(owner, created);
|
|
187
|
+
return created;
|
|
191
188
|
}
|
|
192
189
|
|
|
193
190
|
export function applyRuntimeBrowserSettings(
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
191
|
+
browser: EffectiveBrowserSettings,
|
|
192
|
+
paths: { user: string; project?: string },
|
|
193
|
+
projectTrusted: boolean,
|
|
197
194
|
) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
195
|
+
state.host = browser.host;
|
|
196
|
+
state.port = browser.port;
|
|
197
|
+
state.configuredPort = browser.port;
|
|
198
|
+
state.hostConfigured = browser.hostConfigured;
|
|
199
|
+
state.portConfigured = browser.portConfigured;
|
|
200
|
+
state.autoLaunchEnabled = browser.autoLaunchEnabled;
|
|
201
|
+
state.endpointSource = browser.endpointSource;
|
|
202
|
+
state.autoLaunchSource = browser.autoLaunchSource;
|
|
203
|
+
state.browserExecutable = browser.executablePath;
|
|
204
|
+
state.extensionPaths = [...browser.extensionPaths];
|
|
205
|
+
state.browserExecutableSource = browser.executablePathSource;
|
|
206
|
+
state.extensionPathsSource = browser.extensionPathsSource;
|
|
207
|
+
state.settingsFilePath = paths.user;
|
|
208
|
+
state.projectSettingsFilePath = paths.project;
|
|
209
|
+
state.projectSettingsTrusted = projectTrusted;
|
|
213
210
|
}
|