openbrowser-ai 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 (50) hide show
  1. package/README.md +109 -0
  2. package/dist/commands/doctor.d.ts +5 -0
  3. package/dist/commands/doctor.d.ts.map +1 -0
  4. package/dist/commands/doctor.js +16 -0
  5. package/dist/commands/doctor.js.map +1 -0
  6. package/dist/commands/login.d.ts +4 -0
  7. package/dist/commands/login.d.ts.map +1 -0
  8. package/dist/commands/login.js +6 -0
  9. package/dist/commands/login.js.map +1 -0
  10. package/dist/commands/setup.d.ts +4 -0
  11. package/dist/commands/setup.d.ts.map +1 -0
  12. package/dist/commands/setup.js +6 -0
  13. package/dist/commands/setup.js.map +1 -0
  14. package/dist/commands/status.d.ts +5 -0
  15. package/dist/commands/status.d.ts.map +1 -0
  16. package/dist/commands/status.js +16 -0
  17. package/dist/commands/status.js.map +1 -0
  18. package/dist/index.d.ts +3 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +49 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/lib/chrome-service.d.ts +30 -0
  23. package/dist/lib/chrome-service.d.ts.map +1 -0
  24. package/dist/lib/chrome-service.js +290 -0
  25. package/dist/lib/chrome-service.js.map +1 -0
  26. package/dist/lib/config.d.ts +5 -0
  27. package/dist/lib/config.d.ts.map +1 -0
  28. package/dist/lib/config.js +48 -0
  29. package/dist/lib/config.js.map +1 -0
  30. package/dist/lib/core.d.ts +25 -0
  31. package/dist/lib/core.d.ts.map +1 -0
  32. package/dist/lib/core.js +287 -0
  33. package/dist/lib/core.js.map +1 -0
  34. package/dist/lib/output.d.ts +5 -0
  35. package/dist/lib/output.d.ts.map +1 -0
  36. package/dist/lib/output.js +121 -0
  37. package/dist/lib/output.js.map +1 -0
  38. package/dist/lib/platform.d.ts +9 -0
  39. package/dist/lib/platform.d.ts.map +1 -0
  40. package/dist/lib/platform.js +77 -0
  41. package/dist/lib/platform.js.map +1 -0
  42. package/dist/lib/session.d.ts +9 -0
  43. package/dist/lib/session.d.ts.map +1 -0
  44. package/dist/lib/session.js +72 -0
  45. package/dist/lib/session.js.map +1 -0
  46. package/dist/lib/types.d.ts +53 -0
  47. package/dist/lib/types.d.ts.map +1 -0
  48. package/dist/lib/types.js +18 -0
  49. package/dist/lib/types.js.map +1 -0
  50. package/package.json +62 -0
@@ -0,0 +1,48 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { getConfigDir, getProfileDir } from './platform.js';
4
+ const CONFIG_FILENAME = 'config.json';
5
+ function defaultConfig() {
6
+ return {
7
+ cdpPort: 9222,
8
+ profileDir: getProfileDir(),
9
+ timezone: 'Europe/Berlin',
10
+ vncPassword: 'temp1234',
11
+ vncPort: 5900,
12
+ xvfbDisplay: ':98',
13
+ };
14
+ }
15
+ export function getConfigPath() {
16
+ return join(getConfigDir(), CONFIG_FILENAME);
17
+ }
18
+ export function loadConfig(configPath, overrides) {
19
+ const path = configPath ?? getConfigPath();
20
+ const defaults = defaultConfig();
21
+ let config;
22
+ if (!existsSync(path)) {
23
+ config = defaults;
24
+ }
25
+ else {
26
+ try {
27
+ const raw = readFileSync(path, 'utf-8');
28
+ const parsed = JSON.parse(raw);
29
+ config = { ...defaults, ...parsed };
30
+ }
31
+ catch {
32
+ config = defaults;
33
+ }
34
+ }
35
+ if (overrides) {
36
+ return { ...config, ...overrides };
37
+ }
38
+ return config;
39
+ }
40
+ export function saveConfig(config, configPath) {
41
+ const path = configPath ?? getConfigPath();
42
+ const dir = getConfigDir();
43
+ if (!existsSync(dir)) {
44
+ mkdirSync(dir, { recursive: true });
45
+ }
46
+ writeFileSync(path, JSON.stringify(config, null, 2) + '\n', 'utf-8');
47
+ }
48
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE5D,MAAM,eAAe,GAAG,aAAa,CAAC;AAEtC,SAAS,aAAa;IACpB,OAAO;QACL,OAAO,EAAE,IAAI;QACb,UAAU,EAAE,aAAa,EAAE;QAC3B,QAAQ,EAAE,eAAe;QACzB,WAAW,EAAE,UAAU;QACvB,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,KAAK;KACnB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,YAAY,EAAE,EAAE,eAAe,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,UAAmB,EAAE,SAA2B;IACzE,MAAM,IAAI,GAAG,UAAU,IAAI,aAAa,EAAE,CAAC;IAC3C,MAAM,QAAQ,GAAG,aAAa,EAAE,CAAC;IAEjC,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,GAAG,QAAQ,CAAC;IACpB,CAAC;SAAM,CAAC;QACN,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACxC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;YAClD,MAAM,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,GAAG,QAAQ,CAAC;QACpB,CAAC;IACH,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IACrC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,UAAmB;IAC5D,MAAM,IAAI,GAAG,UAAU,IAAI,aAAa,EAAE,CAAC;IAC3C,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;IAE3B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,CAAC;IAED,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AACvE,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { Browser } from 'playwright-core';
2
+ import type { StatusData, DoctorData, SessionInfo } from './types.js';
3
+ export declare class OpenBrowser {
4
+ private config;
5
+ private sessionManager;
6
+ private chromeService;
7
+ constructor(options?: {
8
+ configPath?: string;
9
+ profileDir?: string;
10
+ });
11
+ connect(): Promise<Browser>;
12
+ getStatus(): Promise<StatusData>;
13
+ getSession(domain: string): Promise<SessionInfo | null>;
14
+ listSessions(): Promise<SessionInfo[]>;
15
+ diagnose(): Promise<DoctorData>;
16
+ login(): Promise<void>;
17
+ private loginMacOS;
18
+ private loginLinux;
19
+ setup(): Promise<{
20
+ servicePath: string;
21
+ mcpConfig: object;
22
+ }>;
23
+ }
24
+ export type { Config, StatusData, SessionInfo, DoctorData, DoctorCheck } from './types.js';
25
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/lib/core.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAEV,UAAU,EACV,UAAU,EAEV,WAAW,EACZ,MAAM,YAAY,CAAC;AAapB,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,aAAa,CAAgB;gBAEzB,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;IAS5D,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAM3B,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC;IA2BhC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAIvD,YAAY,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAItC,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC;IAqI/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAkCd,UAAU;YAcV,UAAU;IA+BlB,KAAK,IAAI,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CA2CnE;AAED,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,287 @@
1
+ import { chromium } from 'playwright-core';
2
+ import { loadConfig, saveConfig } from './config.js';
3
+ import { SessionManager } from './session.js';
4
+ import { ChromeService } from './chrome-service.js';
5
+ import { findChromeBinary, detectOS, getConfigDir, cleanStaleLocks, } from './platform.js';
6
+ import { existsSync, mkdirSync } from 'node:fs';
7
+ import { join } from 'node:path';
8
+ export class OpenBrowser {
9
+ config;
10
+ sessionManager;
11
+ chromeService;
12
+ constructor(options) {
13
+ const overrides = options?.profileDir
14
+ ? { profileDir: options.profileDir }
15
+ : undefined;
16
+ this.config = loadConfig(options?.configPath, overrides);
17
+ this.sessionManager = new SessionManager(this.config.cdpPort);
18
+ this.chromeService = new ChromeService(this.config);
19
+ }
20
+ async connect() {
21
+ return chromium.connectOverCDP(`http://localhost:${this.config.cdpPort}`);
22
+ }
23
+ async getStatus() {
24
+ const cdp = await this.chromeService.getCdpInfo();
25
+ const pid = cdp.running ? await this.chromeService.getPid() : undefined;
26
+ let sessions = [];
27
+ if (cdp.running) {
28
+ try {
29
+ sessions = await this.sessionManager.getSessions();
30
+ }
31
+ catch {
32
+ // CDP connected but cookie read failed
33
+ }
34
+ }
35
+ return {
36
+ chrome: {
37
+ running: cdp.running,
38
+ pid: pid ?? undefined,
39
+ version: cdp.version,
40
+ endpoint: cdp.running
41
+ ? `http://localhost:${this.config.cdpPort}`
42
+ : undefined,
43
+ },
44
+ profile: this.config.profileDir,
45
+ sessions,
46
+ };
47
+ }
48
+ async getSession(domain) {
49
+ return this.sessionManager.getSession(domain);
50
+ }
51
+ async listSessions() {
52
+ return this.sessionManager.getSessions();
53
+ }
54
+ async diagnose() {
55
+ const checks = [];
56
+ // 1. Chrome binary
57
+ const chromeBinary = findChromeBinary();
58
+ if (chromeBinary) {
59
+ checks.push({
60
+ name: 'chrome-binary',
61
+ status: 'pass',
62
+ message: `Found at ${chromeBinary}`,
63
+ });
64
+ }
65
+ else {
66
+ checks.push({
67
+ name: 'chrome-binary',
68
+ status: 'fail',
69
+ message: 'Chrome not found',
70
+ fix: 'Install Google Chrome or Chromium',
71
+ });
72
+ }
73
+ // 2. Profile directory
74
+ if (existsSync(this.config.profileDir)) {
75
+ checks.push({
76
+ name: 'profile-dir',
77
+ status: 'pass',
78
+ message: this.config.profileDir,
79
+ });
80
+ }
81
+ else {
82
+ checks.push({
83
+ name: 'profile-dir',
84
+ status: 'warn',
85
+ message: `Profile directory not found: ${this.config.profileDir}`,
86
+ fix: 'Run: openbrowser setup',
87
+ });
88
+ }
89
+ // 3. Stale locks
90
+ const lockFiles = ['SingletonLock', 'SingletonSocket', 'SingletonCookie'];
91
+ const staleLocks = lockFiles.filter((f) => existsSync(join(this.config.profileDir, f)));
92
+ const cdp = await this.chromeService.getCdpInfo();
93
+ if (staleLocks.length > 0 && !cdp.running) {
94
+ checks.push({
95
+ name: 'stale-locks',
96
+ status: 'warn',
97
+ message: `Stale lock files found: ${staleLocks.join(', ')}`,
98
+ fix: 'Run: openbrowser login (will clean up automatically)',
99
+ });
100
+ }
101
+ else {
102
+ checks.push({
103
+ name: 'stale-locks',
104
+ status: 'pass',
105
+ message: 'No stale lock files',
106
+ });
107
+ }
108
+ // 4. CDP connection
109
+ if (cdp.running) {
110
+ checks.push({
111
+ name: 'cdp-connection',
112
+ status: 'pass',
113
+ message: `Connected to ${cdp.version ?? 'Chrome'} on port ${this.config.cdpPort}`,
114
+ });
115
+ }
116
+ else {
117
+ checks.push({
118
+ name: 'cdp-connection',
119
+ status: 'fail',
120
+ message: `No response on port ${this.config.cdpPort}`,
121
+ fix: 'Start the service: openbrowser setup, then start the service',
122
+ });
123
+ }
124
+ // 5. Session health
125
+ if (cdp.running) {
126
+ try {
127
+ const sessions = await this.sessionManager.getSessions();
128
+ for (const session of sessions) {
129
+ if (session.active && !session.warning) {
130
+ checks.push({
131
+ name: `session-${session.domain}`,
132
+ status: 'pass',
133
+ message: `Active${session.expiresInDays !== undefined ? `, expires in ${session.expiresInDays} days` : ''}`,
134
+ });
135
+ }
136
+ else if (session.active && session.warning) {
137
+ checks.push({
138
+ name: `session-${session.domain}`,
139
+ status: 'warn',
140
+ message: session.warning,
141
+ fix: 'Run: openbrowser login',
142
+ });
143
+ }
144
+ else {
145
+ checks.push({
146
+ name: `session-${session.domain}`,
147
+ status: 'fail',
148
+ message: session.warning ?? 'Not logged in',
149
+ fix: 'Run: openbrowser login',
150
+ });
151
+ }
152
+ }
153
+ }
154
+ catch {
155
+ checks.push({
156
+ name: 'sessions',
157
+ status: 'warn',
158
+ message: 'Could not read session data',
159
+ });
160
+ }
161
+ }
162
+ // 6. Config file
163
+ const configDir = getConfigDir();
164
+ const configFile = `${configDir}/config.json`;
165
+ if (existsSync(configFile)) {
166
+ checks.push({
167
+ name: 'config',
168
+ status: 'pass',
169
+ message: configFile,
170
+ });
171
+ }
172
+ else {
173
+ checks.push({
174
+ name: 'config',
175
+ status: 'warn',
176
+ message: 'No config file (using defaults)',
177
+ fix: 'Run: openbrowser setup',
178
+ });
179
+ }
180
+ const healthy = checks.every((c) => c.status !== 'fail');
181
+ return { checks, healthy };
182
+ }
183
+ async login() {
184
+ const os = detectOS();
185
+ // Stop Chrome service first
186
+ console.log('Stopping Chrome service...');
187
+ this.chromeService.stop();
188
+ // Wait for Chrome to fully stop
189
+ let retries = 10;
190
+ while (retries > 0 && (await this.chromeService.isRunning())) {
191
+ await new Promise((r) => setTimeout(r, 500));
192
+ retries--;
193
+ }
194
+ // Clean stale locks
195
+ cleanStaleLocks(this.config.profileDir);
196
+ if (os === 'linux') {
197
+ await this.loginLinux();
198
+ }
199
+ else {
200
+ await this.loginMacOS();
201
+ }
202
+ // Restart headless service
203
+ console.log('Restarting Chrome service...');
204
+ try {
205
+ this.chromeService.start();
206
+ }
207
+ catch {
208
+ console.log('Could not start service automatically. Start manually or run: openbrowser setup');
209
+ }
210
+ }
211
+ async loginMacOS() {
212
+ console.log('Opening Chrome for login...');
213
+ console.log('Log into your accounts, then close this Chrome window.');
214
+ console.log();
215
+ const chrome = this.chromeService.launchForLogin();
216
+ await new Promise((resolve) => {
217
+ chrome.on('exit', () => resolve());
218
+ });
219
+ console.log('Chrome closed.');
220
+ }
221
+ async loginLinux() {
222
+ // Start Xvfb
223
+ console.log('Starting virtual display...');
224
+ this.chromeService.startXvfb();
225
+ // Launch Chrome on virtual display
226
+ console.log('Starting Chrome on virtual display...');
227
+ const chrome = this.chromeService.launchForLogin();
228
+ // Start VNC
229
+ console.log('Starting VNC server...');
230
+ const vnc = this.chromeService.startVnc();
231
+ console.log();
232
+ console.log(`Connect via: ssh -L ${this.config.vncPort}:localhost:${this.config.vncPort} <host>`);
233
+ console.log(`Then open: vnc://localhost:${this.config.vncPort}`);
234
+ console.log(`Password: ${this.config.vncPassword}`);
235
+ console.log();
236
+ console.log('Log into your accounts, then disconnect VNC.');
237
+ console.log('VNC will auto-close after disconnect.');
238
+ // Wait for VNC to exit (x11vnc -once exits after first disconnect)
239
+ await new Promise((resolve) => {
240
+ vnc.on('exit', () => resolve());
241
+ });
242
+ // Kill Chrome on virtual display
243
+ chrome.kill();
244
+ console.log('VNC disconnected. Chrome closed.');
245
+ }
246
+ async setup() {
247
+ // Ensure directories exist
248
+ const configDir = getConfigDir();
249
+ if (!existsSync(configDir)) {
250
+ mkdirSync(configDir, { recursive: true });
251
+ }
252
+ if (!existsSync(this.config.profileDir)) {
253
+ mkdirSync(this.config.profileDir, { recursive: true });
254
+ }
255
+ // Save default config
256
+ saveConfig(this.config);
257
+ // Install service
258
+ let servicePath;
259
+ let instructions;
260
+ try {
261
+ const result = this.chromeService.install();
262
+ servicePath = result.path;
263
+ instructions = result.instructions;
264
+ }
265
+ catch (err) {
266
+ const msg = err instanceof Error ? err.message : String(err);
267
+ if (msg.includes('EACCES') || msg.includes('permission denied')) {
268
+ console.error(`Permission denied writing service file.`);
269
+ console.error('On Linux, run with sudo: sudo npx openbrowser setup');
270
+ console.error('Or the service will be installed in user mode if available.');
271
+ process.exit(1);
272
+ }
273
+ throw err;
274
+ }
275
+ console.log('Setup complete.');
276
+ console.log();
277
+ console.log(instructions);
278
+ console.log();
279
+ console.log('MCP configuration (add to your claude_desktop_config.json):');
280
+ const mcpConfig = this.chromeService.getMcpConfig();
281
+ console.log(JSON.stringify(mcpConfig, null, 2));
282
+ console.log();
283
+ console.log('Next step: openbrowser login');
284
+ return { servicePath, mcpConfig };
285
+ }
286
+ }
287
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/lib/core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { CommandOutput } from './types.js';
2
+ export declare function createOutput<T>(command: string, data: T, summary: string, success?: boolean, error?: string): CommandOutput<T>;
3
+ export declare function resolveFormat(explicit?: string): 'json' | 'text';
4
+ export declare function printOutput<T>(output: CommandOutput<T>, format: 'json' | 'text'): void;
5
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/lib/output.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,aAAa,EAId,MAAM,YAAY,CAAC;AAapB,wBAAgB,YAAY,CAAC,CAAC,EAC5B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,MAAM,EACf,OAAO,UAAO,EACd,KAAK,CAAC,EAAE,MAAM,GACb,aAAa,CAAC,CAAC,CAAC,CAUlB;AAED,wBAAgB,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAIhE;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBtF"}
@@ -0,0 +1,121 @@
1
+ import chalk from 'chalk';
2
+ import { readFileSync } from 'node:fs';
3
+ import { join, dirname } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ function getVersion() {
6
+ try {
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ const pkgPath = join(__dirname, '..', '..', 'package.json');
9
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
10
+ return pkg.version ?? '0.0.0';
11
+ }
12
+ catch {
13
+ return '0.0.0';
14
+ }
15
+ }
16
+ export function createOutput(command, data, summary, success = true, error) {
17
+ return {
18
+ command,
19
+ version: getVersion(),
20
+ timestamp: new Date().toISOString(),
21
+ success,
22
+ ...(error ? { error } : {}),
23
+ data,
24
+ summary,
25
+ };
26
+ }
27
+ export function resolveFormat(explicit) {
28
+ if (explicit === 'json')
29
+ return 'json';
30
+ if (explicit === 'text')
31
+ return 'text';
32
+ return process.stdout.isTTY ? 'text' : 'json';
33
+ }
34
+ export function printOutput(output, format) {
35
+ if (format === 'json') {
36
+ console.log(JSON.stringify(output, null, 2));
37
+ return;
38
+ }
39
+ // Text formatting depends on the command
40
+ switch (output.command) {
41
+ case 'status':
42
+ printStatusText(output);
43
+ break;
44
+ case 'doctor':
45
+ printDoctorText(output);
46
+ break;
47
+ default:
48
+ console.log(output.summary);
49
+ }
50
+ }
51
+ function printStatusText(output) {
52
+ const { data } = output;
53
+ console.log();
54
+ console.log(chalk.bold('Chrome'));
55
+ if (data.chrome.running) {
56
+ console.log(` Status: ${chalk.green('running')}${data.chrome.pid ? ` (pid ${data.chrome.pid})` : ''}`);
57
+ console.log(` Version: ${data.chrome.version ?? 'unknown'}`);
58
+ console.log(` Endpoint: ${data.chrome.endpoint ?? 'unknown'}`);
59
+ }
60
+ else {
61
+ console.log(` Status: ${chalk.red('not running')}`);
62
+ }
63
+ console.log(` Profile: ${data.profile}`);
64
+ console.log();
65
+ console.log(chalk.bold('Sessions'));
66
+ if (data.sessions.length === 0) {
67
+ console.log(' No tracked sessions.');
68
+ }
69
+ else {
70
+ for (const session of data.sessions) {
71
+ printSessionLine(session);
72
+ }
73
+ }
74
+ console.log();
75
+ }
76
+ function printSessionLine(session) {
77
+ const domain = session.domain.padEnd(16);
78
+ if (!session.active) {
79
+ const reason = session.warning ?? 'inactive';
80
+ console.log(` ${domain} ${chalk.red('inactive')} ${chalk.dim(reason)}`);
81
+ return;
82
+ }
83
+ let expiry = '';
84
+ if (session.expiresInDays !== undefined) {
85
+ expiry = `expires in ${session.expiresInDays} day${session.expiresInDays === 1 ? '' : 's'}`;
86
+ }
87
+ if (session.warning) {
88
+ console.log(` ${domain} ${chalk.yellow('active')} ${expiry} ${chalk.yellow('[!]')}`);
89
+ }
90
+ else {
91
+ console.log(` ${domain} ${chalk.green('active')} ${expiry}`);
92
+ }
93
+ }
94
+ function printDoctorText(output) {
95
+ const { data } = output;
96
+ console.log();
97
+ console.log(chalk.bold('OpenBrowser Doctor'));
98
+ console.log();
99
+ for (const check of data.checks) {
100
+ const icon = check.status === 'pass'
101
+ ? chalk.green('PASS')
102
+ : check.status === 'warn'
103
+ ? chalk.yellow('WARN')
104
+ : chalk.red('FAIL');
105
+ console.log(` ${icon} ${check.name}: ${check.message}`);
106
+ if (check.fix) {
107
+ console.log(` ${chalk.dim('Fix:')} ${check.fix}`);
108
+ }
109
+ }
110
+ console.log();
111
+ if (data.healthy) {
112
+ console.log(chalk.green('All checks passed.'));
113
+ }
114
+ else {
115
+ const fails = data.checks.filter((c) => c.status === 'fail').length;
116
+ const warns = data.checks.filter((c) => c.status === 'warn').length;
117
+ console.log(chalk.red(`${fails} failure${fails === 1 ? '' : 's'}, ${warns} warning${warns === 1 ? '' : 's'}`));
118
+ }
119
+ console.log();
120
+ }
121
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/lib/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export type Platform = 'darwin' | 'linux';
2
+ export declare function assertSupportedPlatform(): void;
3
+ export declare function detectOS(): Platform;
4
+ export declare function findChromeBinary(): string | null;
5
+ export declare function getConfigDir(): string;
6
+ export declare function getProfileDir(): string;
7
+ export declare function isHeadless(): boolean;
8
+ export declare function cleanStaleLocks(profileDir: string): void;
9
+ //# sourceMappingURL=platform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../src/lib/platform.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1C,wBAAgB,uBAAuB,IAAI,IAAI,CAY9C;AAED,wBAAgB,QAAQ,IAAI,QAAQ,CAEnC;AAeD,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAmBhD;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,UAAU,IAAI,OAAO,CAIpC;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAYxD"}
@@ -0,0 +1,77 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { existsSync, unlinkSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ export function assertSupportedPlatform() {
6
+ if (process.platform === 'win32') {
7
+ console.error('OpenBrowser supports macOS and Linux only.');
8
+ console.error('Track Windows support: https://github.com/federicodeponte/openbrowser/issues/1');
9
+ process.exit(1);
10
+ }
11
+ if (process.platform !== 'darwin' && process.platform !== 'linux') {
12
+ console.error(`Unsupported platform: ${process.platform}`);
13
+ process.exit(1);
14
+ }
15
+ }
16
+ export function detectOS() {
17
+ return process.platform;
18
+ }
19
+ const CHROME_PATHS_DARWIN = [
20
+ '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
21
+ '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
22
+ '/Applications/Chromium.app/Contents/MacOS/Chromium',
23
+ ];
24
+ const CHROME_PATHS_LINUX = [
25
+ 'google-chrome-stable',
26
+ 'google-chrome',
27
+ 'chromium-browser',
28
+ 'chromium',
29
+ ];
30
+ export function findChromeBinary() {
31
+ const os = detectOS();
32
+ if (os === 'darwin') {
33
+ for (const path of CHROME_PATHS_DARWIN) {
34
+ if (existsSync(path))
35
+ return path;
36
+ }
37
+ return null;
38
+ }
39
+ for (const name of CHROME_PATHS_LINUX) {
40
+ try {
41
+ const path = execSync(`which ${name}`, { encoding: 'utf-8' }).trim();
42
+ if (path)
43
+ return path;
44
+ }
45
+ catch {
46
+ // not found, try next
47
+ }
48
+ }
49
+ return null;
50
+ }
51
+ export function getConfigDir() {
52
+ return join(homedir(), '.openbrowser');
53
+ }
54
+ export function getProfileDir() {
55
+ return join(getConfigDir(), 'chrome-profile');
56
+ }
57
+ export function isHeadless() {
58
+ if (detectOS() === 'darwin')
59
+ return false;
60
+ // Linux: check if a display is available
61
+ return !process.env['DISPLAY'] || process.env['DISPLAY'] === ':98';
62
+ }
63
+ export function cleanStaleLocks(profileDir) {
64
+ const lockFiles = ['SingletonLock', 'SingletonSocket', 'SingletonCookie'];
65
+ for (const file of lockFiles) {
66
+ const path = join(profileDir, file);
67
+ try {
68
+ if (existsSync(path)) {
69
+ unlinkSync(path);
70
+ }
71
+ }
72
+ catch {
73
+ // ignore errors (e.g., file already gone)
74
+ }
75
+ }
76
+ }
77
+ //# sourceMappingURL=platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.js","sourceRoot":"","sources":["../../src/lib/platform.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { SessionInfo } from './types.js';
2
+ export declare class SessionManager {
3
+ private cdpEndpoint;
4
+ constructor(cdpPort: number);
5
+ getSessions(): Promise<SessionInfo[]>;
6
+ getSession(domain: string): Promise<SessionInfo | null>;
7
+ private analyzeSession;
8
+ }
9
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/lib/session.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAG9D,qBAAa,cAAc;IACzB,OAAO,CAAC,WAAW,CAAS;gBAEhB,OAAO,EAAE,MAAM;IAIrB,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAuBrC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAK7D,OAAO,CAAC,cAAc;CAqDvB"}