sliccy 0.1.0

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.
Files changed (63) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +512 -0
  3. package/dist/cli/chrome-launch.d.ts +47 -0
  4. package/dist/cli/chrome-launch.js +324 -0
  5. package/dist/cli/cli-log-dedup.d.ts +19 -0
  6. package/dist/cli/cli-log-dedup.js +62 -0
  7. package/dist/cli/electron-controller.d.ts +38 -0
  8. package/dist/cli/electron-controller.js +287 -0
  9. package/dist/cli/electron-main.d.ts +1 -0
  10. package/dist/cli/electron-main.js +183 -0
  11. package/dist/cli/electron-runtime.d.ts +58 -0
  12. package/dist/cli/electron-runtime.js +133 -0
  13. package/dist/cli/file-logger.d.ts +38 -0
  14. package/dist/cli/file-logger.js +207 -0
  15. package/dist/cli/index.d.ts +2 -0
  16. package/dist/cli/index.js +1023 -0
  17. package/dist/cli/launch-url.d.ts +9 -0
  18. package/dist/cli/launch-url.js +34 -0
  19. package/dist/cli/qa-setup.d.ts +1 -0
  20. package/dist/cli/qa-setup.js +36 -0
  21. package/dist/cli/release-package.d.ts +17 -0
  22. package/dist/cli/release-package.js +232 -0
  23. package/dist/cli/runtime-flags.d.ts +21 -0
  24. package/dist/cli/runtime-flags.js +154 -0
  25. package/dist/cli/sync-release-version.d.ts +2 -0
  26. package/dist/cli/sync-release-version.js +34 -0
  27. package/dist/tray-url-shared.d.ts +11 -0
  28. package/dist/tray-url-shared.js +56 -0
  29. package/dist/ui/assets/___vite-browser-external_commonjs-proxy-7ULRRj69.js +1 -0
  30. package/dist/ui/assets/__vite-browser-external-D7Ct-6yo.js +1 -0
  31. package/dist/ui/assets/addon-fit-DOCEibfw.js +12 -0
  32. package/dist/ui/assets/bsh-watchdog-D19WB0U1.js +2 -0
  33. package/dist/ui/assets/index-BVQAdk-Y.js +8 -0
  34. package/dist/ui/assets/index-BjJrFm2K.js +43 -0
  35. package/dist/ui/assets/index-C1dglHrI.js +3 -0
  36. package/dist/ui/assets/index-D3Enm5ux.js +13091 -0
  37. package/dist/ui/assets/index-D7hjyFh1.js +2 -0
  38. package/dist/ui/assets/index-D8uSC2sl.js +45 -0
  39. package/dist/ui/assets/index-DEglHp2j.js +1 -0
  40. package/dist/ui/assets/index-DvjzakYY.js +14406 -0
  41. package/dist/ui/assets/index-deZeJCgO.js +1 -0
  42. package/dist/ui/assets/index-mz3VYh0I.js +131 -0
  43. package/dist/ui/assets/index-r2m8Dpaz.js +54 -0
  44. package/dist/ui/assets/index-ygVJ3eFG.js +11 -0
  45. package/dist/ui/assets/lick-manager-proxy-G3WuipZ-.js +1 -0
  46. package/dist/ui/assets/magic-string.es-BPLJknd7.js +10 -0
  47. package/dist/ui/assets/oauth-service-DIahkF-o.js +1 -0
  48. package/dist/ui/assets/offscreen-client-ByVIJGHW.js +1 -0
  49. package/dist/ui/assets/pdfjs-uyZuKmOq.js +59 -0
  50. package/dist/ui/assets/pyodide-D73G_Ygx.mjs +4 -0
  51. package/dist/ui/assets/sql-wasm-BggYNCID.js +2 -0
  52. package/dist/ui/assets/stream-lEC9OYG2.js +1 -0
  53. package/dist/ui/assets/xterm-Bb8UKAlD.js +27 -0
  54. package/dist/ui/assets/xterm-DOrYoP_4.css +32 -0
  55. package/dist/ui/electron-overlay-entry.js +360 -0
  56. package/dist/ui/favicon.png +0 -0
  57. package/dist/ui/fonts/AdobeClean-Bold.otf +0 -0
  58. package/dist/ui/fonts/AdobeClean-ExtraBold.otf +0 -0
  59. package/dist/ui/fonts/AdobeClean-Medium.otf +0 -0
  60. package/dist/ui/fonts/AdobeClean-Regular.otf +0 -0
  61. package/dist/ui/index.html +1981 -0
  62. package/dist/ui/preview-sw.js +4 -0
  63. package/package.json +81 -0
@@ -0,0 +1,324 @@
1
+ import { existsSync, readdirSync } from 'fs';
2
+ import { mkdir, readFile, writeFile } from 'fs/promises';
3
+ import { homedir } from 'os';
4
+ import { dirname, join } from 'path';
5
+ export const CLI_PROFILE_NAMES = ['leader', 'follower', 'extension'];
6
+ const DEFAULT_USER_DATA_DIR_NAME = 'browser-coding-agent-chrome';
7
+ const QA_PROFILE_ROOT_SEGMENTS = ['.qa', 'chrome'];
8
+ function argbToSignedInt(argbHex) {
9
+ return argbHex | 0;
10
+ }
11
+ const CLI_PROFILE_DEFINITIONS = {
12
+ leader: {
13
+ displayName: 'SLICC QA Leader',
14
+ avatarIndex: 0,
15
+ avatarIcon: 'chrome://theme/IDR_PROFILE_AVATAR_0',
16
+ profileColorSeed: argbToSignedInt(0xff4285f4),
17
+ profileHighlightColor: argbToSignedInt(0xff4285f4),
18
+ loadsExtension: false,
19
+ },
20
+ follower: {
21
+ displayName: 'SLICC QA Follower',
22
+ avatarIndex: 7,
23
+ avatarIcon: 'chrome://theme/IDR_PROFILE_AVATAR_7',
24
+ profileColorSeed: argbToSignedInt(0xff34a853),
25
+ profileHighlightColor: argbToSignedInt(0xff34a853),
26
+ loadsExtension: false,
27
+ },
28
+ extension: {
29
+ displayName: 'SLICC QA Extension',
30
+ avatarIndex: 19,
31
+ avatarIcon: 'chrome://theme/IDR_PROFILE_AVATAR_19',
32
+ profileColorSeed: argbToSignedInt(0xffa142f4),
33
+ profileHighlightColor: argbToSignedInt(0xffa142f4),
34
+ loadsExtension: true,
35
+ },
36
+ };
37
+ function isJsonObject(value) {
38
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
39
+ }
40
+ function ensureObject(parent, key) {
41
+ const existing = parent[key];
42
+ if (isJsonObject(existing))
43
+ return existing;
44
+ const next = {};
45
+ parent[key] = next;
46
+ return next;
47
+ }
48
+ function normalizeProfileName(profile) {
49
+ const trimmed = profile?.trim();
50
+ return trimmed ? trimmed : null;
51
+ }
52
+ export function isCliProfileName(value) {
53
+ return CLI_PROFILE_NAMES.includes(value ?? '');
54
+ }
55
+ export function resolveQaProfilesRoot(projectRoot) {
56
+ return join(projectRoot, ...QA_PROFILE_ROOT_SEGMENTS);
57
+ }
58
+ export function resolveDefaultChromeUserDataDir(tmpDir = process.env['TMPDIR'] ?? '/tmp') {
59
+ return join(tmpDir, DEFAULT_USER_DATA_DIR_NAME);
60
+ }
61
+ export function resolveChromeLaunchProfile(options) {
62
+ const profile = normalizeProfileName(options.profile);
63
+ if (!profile) {
64
+ return {
65
+ id: null,
66
+ displayName: 'Chrome',
67
+ userDataDir: resolveDefaultChromeUserDataDir(options.tmpDir ?? undefined),
68
+ extensionPath: null,
69
+ };
70
+ }
71
+ if (!isCliProfileName(profile)) {
72
+ throw new Error(`Unknown Chrome profile "${profile}". Supported values: ${CLI_PROFILE_NAMES.join(', ')}.`);
73
+ }
74
+ const definition = CLI_PROFILE_DEFINITIONS[profile];
75
+ return {
76
+ id: profile,
77
+ displayName: definition.displayName,
78
+ userDataDir: join(resolveQaProfilesRoot(options.projectRoot), profile),
79
+ extensionPath: definition.loadsExtension ? join(options.projectRoot, 'dist', 'extension') : null,
80
+ };
81
+ }
82
+ export function buildChromeLaunchArgs(options) {
83
+ const args = [
84
+ `--remote-debugging-port=${options.cdpPort}`,
85
+ '--no-first-run',
86
+ '--no-default-browser-check',
87
+ `--user-data-dir=${options.profile.userDataDir}`,
88
+ ];
89
+ if (options.profile.extensionPath) {
90
+ args.push(`--disable-extensions-except=${options.profile.extensionPath}`);
91
+ args.push(`--load-extension=${options.profile.extensionPath}`);
92
+ }
93
+ args.push(options.launchUrl);
94
+ return args;
95
+ }
96
+ function findPuppeteerChromeForTesting(options) {
97
+ const cacheRoot = join(options.homeDir, '.cache', 'puppeteer', 'chrome');
98
+ let entries;
99
+ try {
100
+ entries = options.readdirSyncImpl(cacheRoot);
101
+ }
102
+ catch {
103
+ return null;
104
+ }
105
+ const prefix = options.platform === 'darwin'
106
+ ? /^mac/i
107
+ : options.platform === 'linux'
108
+ ? /^linux/i
109
+ : options.platform === 'win32'
110
+ ? /^win/i
111
+ : null;
112
+ if (!prefix)
113
+ return null;
114
+ const executableSuffixes = options.platform === 'darwin'
115
+ ? [
116
+ join('chrome-mac-arm64', 'Google Chrome for Testing.app', 'Contents', 'MacOS', 'Google Chrome for Testing'),
117
+ join('chrome-mac-x64', 'Google Chrome for Testing.app', 'Contents', 'MacOS', 'Google Chrome for Testing'),
118
+ ]
119
+ : options.platform === 'linux'
120
+ ? [join('chrome-linux64', 'chrome'), join('chrome-linux', 'chrome')]
121
+ : [join('chrome-win64', 'chrome.exe'), join('chrome-win32', 'chrome.exe')];
122
+ const sortedEntries = entries
123
+ .filter((entry) => prefix.test(entry))
124
+ .sort((left, right) => right.localeCompare(left, undefined, { numeric: true }));
125
+ for (const entry of sortedEntries) {
126
+ for (const suffix of executableSuffixes) {
127
+ const candidate = join(cacheRoot, entry, suffix);
128
+ if (options.existsSyncImpl(candidate)) {
129
+ return candidate;
130
+ }
131
+ }
132
+ }
133
+ return null;
134
+ }
135
+ /**
136
+ * On macOS, if a path points to a `.app` bundle, resolve it to the inner
137
+ * `Contents/MacOS/<name>` executable. Returns `null` if the path is not a
138
+ * `.app` bundle or the inner executable does not exist.
139
+ */
140
+ function resolveMacAppBundle(appPath, platform, existsSyncImpl) {
141
+ if (platform !== 'darwin' || !appPath.endsWith('.app'))
142
+ return null;
143
+ // Derive the binary name from the bundle name:
144
+ // "Google Chrome.app" → "Google Chrome"
145
+ const bundleName = appPath.split('/').pop().replace(/\.app$/, '');
146
+ const candidate = join(appPath, 'Contents', 'MacOS', bundleName);
147
+ return existsSyncImpl(candidate) ? candidate : null;
148
+ }
149
+ function findInstalledChrome(options) {
150
+ const candidates = {
151
+ darwin: [
152
+ '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
153
+ '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
154
+ '/Applications/Chromium.app/Contents/MacOS/Chromium',
155
+ ],
156
+ linux: [
157
+ '/usr/bin/google-chrome',
158
+ '/usr/bin/google-chrome-stable',
159
+ '/usr/bin/chromium',
160
+ '/usr/bin/chromium-browser',
161
+ '/snap/bin/chromium',
162
+ ],
163
+ win32: [
164
+ `${options.env['LOCALAPPDATA']}\\Google\\Chrome\\Application\\chrome.exe`,
165
+ `${options.env['PROGRAMFILES']}\\Google\\Chrome\\Application\\chrome.exe`,
166
+ `${options.env['PROGRAMFILES(X86)']}\\Google\\Chrome\\Application\\chrome.exe`,
167
+ ],
168
+ };
169
+ for (const candidate of candidates[options.platform] ?? []) {
170
+ if (candidate && options.existsSyncImpl(candidate)) {
171
+ return candidate;
172
+ }
173
+ }
174
+ return null;
175
+ }
176
+ export function findChromeExecutable(options = {}) {
177
+ const env = options.env ?? process.env;
178
+ const existsSyncImpl = options.existsSyncImpl ?? existsSync;
179
+ const readdirSyncImpl = options.readdirSyncImpl ?? readdirSync;
180
+ const platform = options.platform ?? process.platform;
181
+ const homeDir = options.homeDir ?? homedir();
182
+ const executablePreference = options.executablePreference ?? 'chrome-for-testing';
183
+ const envPath = env['CHROME_PATH'];
184
+ if (envPath && existsSyncImpl(envPath)) {
185
+ const resolved = resolveMacAppBundle(envPath, platform, existsSyncImpl);
186
+ return resolved ?? envPath;
187
+ }
188
+ const installedChrome = findInstalledChrome({
189
+ env,
190
+ platform,
191
+ existsSyncImpl,
192
+ });
193
+ const chromeForTesting = findPuppeteerChromeForTesting({
194
+ platform,
195
+ homeDir,
196
+ existsSyncImpl,
197
+ readdirSyncImpl,
198
+ });
199
+ return executablePreference === 'installed'
200
+ ? installedChrome ?? chromeForTesting
201
+ : chromeForTesting ?? installedChrome;
202
+ }
203
+ async function readJsonFile(filePath) {
204
+ try {
205
+ const raw = await readFile(filePath, 'utf8');
206
+ const parsed = JSON.parse(raw);
207
+ return isJsonObject(parsed) ? parsed : {};
208
+ }
209
+ catch {
210
+ return {};
211
+ }
212
+ }
213
+ async function writeJsonFile(filePath, value) {
214
+ await mkdir(dirname(filePath), { recursive: true });
215
+ await writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
216
+ }
217
+ function seedLocalState(localState, definition) {
218
+ const browser = ensureObject(localState, 'browser');
219
+ browser['check_default_browser'] = false;
220
+ browser['has_seen_welcome_page'] = true;
221
+ const profile = ensureObject(localState, 'profile');
222
+ profile['last_used'] = 'Default';
223
+ profile['picker_shown'] = true;
224
+ profile['profiles_order'] = ['Default'];
225
+ profile['last_active_profiles'] = ['Default'];
226
+ const infoCache = ensureObject(profile, 'info_cache');
227
+ const defaultProfile = ensureObject(infoCache, 'Default');
228
+ defaultProfile['name'] = definition.displayName;
229
+ defaultProfile['avatar_icon'] = definition.avatarIcon;
230
+ defaultProfile['is_using_default_name'] = false;
231
+ defaultProfile['is_using_default_avatar'] = true;
232
+ defaultProfile['profile_color_seed'] = definition.profileColorSeed;
233
+ defaultProfile['profile_highlight_color'] = definition.profileHighlightColor;
234
+ return localState;
235
+ }
236
+ function seedPreferences(preferences, definition) {
237
+ const profile = ensureObject(preferences, 'profile');
238
+ profile['name'] = definition.displayName;
239
+ profile['avatar_index'] = definition.avatarIndex;
240
+ profile['using_default_name'] = false;
241
+ profile['using_default_avatar'] = true;
242
+ const browser = ensureObject(preferences, 'browser');
243
+ browser['has_seen_welcome_page'] = true;
244
+ const bookmarkBar = ensureObject(preferences, 'bookmark_bar');
245
+ bookmarkBar['show_on_all_tabs'] = false;
246
+ const signin = ensureObject(preferences, 'signin');
247
+ signin['allowed'] = false;
248
+ return preferences;
249
+ }
250
+ export async function ensureQaProfileScaffold(projectRoot) {
251
+ const profiles = CLI_PROFILE_NAMES.map((profileName) => resolveChromeLaunchProfile({ projectRoot, profile: profileName }));
252
+ for (const profile of profiles) {
253
+ const definition = CLI_PROFILE_DEFINITIONS[profile.id];
254
+ await mkdir(join(profile.userDataDir, 'Default'), { recursive: true });
255
+ await writeFile(join(profile.userDataDir, 'First Run'), '', 'utf8');
256
+ const localStatePath = join(profile.userDataDir, 'Local State');
257
+ const preferencesPath = join(profile.userDataDir, 'Default', 'Preferences');
258
+ const localState = seedLocalState(await readJsonFile(localStatePath), definition);
259
+ const preferences = seedPreferences(await readJsonFile(preferencesPath), definition);
260
+ await writeJsonFile(localStatePath, localState);
261
+ await writeJsonFile(preferencesPath, preferences);
262
+ }
263
+ return profiles;
264
+ }
265
+ // ---------------------------------------------------------------------------
266
+ // CDP port parsing — extract actual port from Chrome's stderr output
267
+ // ---------------------------------------------------------------------------
268
+ /**
269
+ * Parse the CDP port from a Chrome stderr line.
270
+ * Chrome prints `DevTools listening on ws://HOST:PORT/devtools/browser/ID`
271
+ * to stderr when it starts. Returns the port number, or null if the line
272
+ * doesn't match.
273
+ */
274
+ export function parseCdpPortFromStderr(line) {
275
+ const match = line.match(/DevTools listening on ws:\/\/[^:]+:(\d+)\//);
276
+ if (!match)
277
+ return null;
278
+ const port = Number.parseInt(match[1], 10);
279
+ return Number.isFinite(port) && port > 0 ? port : null;
280
+ }
281
+ /**
282
+ * Watch a Chrome child process's stderr for the `DevTools listening on` line
283
+ * and resolve with the actual CDP port. Rejects after `timeoutMs` if the line
284
+ * never appears (e.g. Chrome failed to start).
285
+ */
286
+ export function waitForCdpPortFromStderr(child, timeoutMs = 15000) {
287
+ return new Promise((resolve, reject) => {
288
+ if (!child.stderr) {
289
+ reject(new Error('Chrome process has no stderr stream'));
290
+ return;
291
+ }
292
+ let settled = false;
293
+ const timer = setTimeout(() => {
294
+ if (!settled) {
295
+ settled = true;
296
+ reject(new Error(`Timed out waiting for Chrome CDP port (${timeoutMs}ms)`));
297
+ }
298
+ }, timeoutMs);
299
+ const onData = (chunk) => {
300
+ if (settled)
301
+ return;
302
+ const text = chunk.toString('utf-8');
303
+ // stderr may deliver multiple lines in one chunk
304
+ for (const line of text.split('\n')) {
305
+ const port = parseCdpPortFromStderr(line);
306
+ if (port !== null) {
307
+ settled = true;
308
+ clearTimeout(timer);
309
+ child.stderr.off('data', onData);
310
+ resolve(port);
311
+ return;
312
+ }
313
+ }
314
+ };
315
+ child.stderr.on('data', onData);
316
+ child.on('exit', (code) => {
317
+ if (!settled) {
318
+ settled = true;
319
+ clearTimeout(timer);
320
+ reject(new Error(`Chrome exited with code ${code} before reporting CDP port`));
321
+ }
322
+ });
323
+ });
324
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Lightweight log deduplication for CLI-side console output.
3
+ *
4
+ * Fingerprints messages by replacing variable parts (numbers, IDs, hex, JSON blobs)
5
+ * with placeholders, then suppresses duplicates within a sliding window.
6
+ * Periodically flushes suppression counts so the operator knows what was hidden.
7
+ */
8
+ export declare class CliLogDedup {
9
+ private entries;
10
+ private prefix;
11
+ constructor(prefix?: string);
12
+ /**
13
+ * Returns true if the message should be printed, false if suppressed.
14
+ * Automatically flushes stale entries and emits suppression summaries.
15
+ */
16
+ shouldLog(message: string): boolean;
17
+ private evict;
18
+ private flushEntry;
19
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Lightweight log deduplication for CLI-side console output.
3
+ *
4
+ * Fingerprints messages by replacing variable parts (numbers, IDs, hex, JSON blobs)
5
+ * with placeholders, then suppresses duplicates within a sliding window.
6
+ * Periodically flushes suppression counts so the operator knows what was hidden.
7
+ */
8
+ const BUFFER_SIZE = 10;
9
+ const WINDOW_MS = 60_000; // 1 minute
10
+ function makeFingerprint(message) {
11
+ return message
12
+ // UUIDs
13
+ .replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, '<id>')
14
+ // Hex strings (8+ chars, e.g. session IDs, target IDs)
15
+ .replace(/\b[0-9A-Fa-f]{8,}\b/g, '<hex>')
16
+ // JSON object/array blobs — collapse {...} and [...]
17
+ .replace(/\{[^}]{20,}\}/g, '{…}')
18
+ .replace(/\[[^\]]{20,}\]/g, '[…]')
19
+ // Numbers (integers and floats)
20
+ .replace(/\b\d+(\.\d+)?\b/g, '<n>');
21
+ }
22
+ export class CliLogDedup {
23
+ entries = [];
24
+ prefix;
25
+ constructor(prefix = '[cdp-proxy]') {
26
+ this.prefix = prefix;
27
+ }
28
+ /**
29
+ * Returns true if the message should be printed, false if suppressed.
30
+ * Automatically flushes stale entries and emits suppression summaries.
31
+ */
32
+ shouldLog(message) {
33
+ const fp = makeFingerprint(message);
34
+ const now = Date.now();
35
+ // Evict stale entries
36
+ this.evict(now);
37
+ // Check for existing match
38
+ const existing = this.entries.find(e => e.fingerprint === fp);
39
+ if (existing) {
40
+ existing.count++;
41
+ return false;
42
+ }
43
+ // New entry — evict oldest if buffer full
44
+ if (this.entries.length >= BUFFER_SIZE) {
45
+ const evicted = this.entries.shift();
46
+ this.flushEntry(evicted);
47
+ }
48
+ this.entries.push({ fingerprint: fp, count: 0, firstSeen: now, sample: message.slice(0, 120) });
49
+ return true;
50
+ }
51
+ evict(now) {
52
+ while (this.entries.length > 0 && now - this.entries[0].firstSeen > WINDOW_MS) {
53
+ const evicted = this.entries.shift();
54
+ this.flushEntry(evicted);
55
+ }
56
+ }
57
+ flushEntry(entry) {
58
+ if (entry.count > 0) {
59
+ console.log(`${this.prefix} (suppressed ${entry.count} similar: "${entry.sample}")`);
60
+ }
61
+ }
62
+ }
@@ -0,0 +1,38 @@
1
+ import { type ChildProcess } from 'child_process';
2
+ interface RunningProcessInfo {
3
+ pid: number;
4
+ commandLine: string;
5
+ executablePath: string | null;
6
+ }
7
+ export declare function findMatchingElectronAppPids(runningProcesses: RunningProcessInfo[], processMatchPatterns: string[], currentPid?: number): number[];
8
+ export declare class ElectronAppAlreadyRunningError extends Error {
9
+ constructor(message: string);
10
+ }
11
+ export declare function launchElectronApp(options: {
12
+ appPath: string;
13
+ cdpPort: number;
14
+ kill: boolean;
15
+ platform?: NodeJS.Platform;
16
+ }): Promise<{
17
+ child: ChildProcess;
18
+ displayName: string;
19
+ }>;
20
+ export declare class ElectronOverlayInjector {
21
+ private readonly cdpPort;
22
+ private readonly bootstrapScript;
23
+ private readonly connections;
24
+ private syncTimer;
25
+ private syncing;
26
+ private constructor();
27
+ static create(options: {
28
+ cdpPort: number;
29
+ servePort: number;
30
+ dev: boolean;
31
+ projectRoot: string;
32
+ }): Promise<ElectronOverlayInjector>;
33
+ start(): Promise<void>;
34
+ stop(): void;
35
+ private syncTargets;
36
+ private connectToTarget;
37
+ }
38
+ export {};