vibium 0.0.1 → 0.1.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Vibium
2
2
 
3
- A minimal npm package for now. Just logs a welcome message to the console. More coming!
3
+ Browser automation for AI agents and humans.
4
4
 
5
5
  ## Installation
6
6
 
@@ -8,14 +8,220 @@ A minimal npm package for now. Just logs a welcome message to the console. More
8
8
  npm install vibium
9
9
  ```
10
10
 
11
- ## Usage
11
+ This automatically downloads Chrome for Testing on first install.
12
12
 
13
- ```js
14
- const vibium = require('vibium');
13
+ ## Quick Start
15
14
 
16
- vibium(); // Logs: "Welcome to Vibium!"
15
+ ### Async API
16
+
17
+ ```javascript
18
+ import { browser } from 'vibium';
19
+ import { writeFile } from 'fs/promises';
20
+
21
+ const vibe = await browser.launch();
22
+ await vibe.go('https://example.com');
23
+
24
+ const link = await vibe.find('a');
25
+ console.log(await link.text());
26
+ await link.click();
27
+
28
+ const screenshot = await vibe.screenshot();
29
+ await writeFile('screenshot.png', screenshot);
30
+
31
+ await vibe.quit();
32
+ ```
33
+
34
+ ### Sync API
35
+
36
+ ```javascript
37
+ import { browserSync } from 'vibium';
38
+ import { writeFileSync } from 'fs';
39
+
40
+ const vibe = browserSync.launch();
41
+ vibe.go('https://example.com');
42
+
43
+ const link = vibe.find('a');
44
+ console.log(link.text());
45
+ link.click();
46
+
47
+ const screenshot = vibe.screenshot();
48
+ writeFileSync('screenshot.png', screenshot);
49
+
50
+ vibe.quit();
51
+ ```
52
+
53
+ ## API Reference
54
+
55
+ ### browser.launch(options?)
56
+
57
+ Launch a new browser session.
58
+
59
+ ```javascript
60
+ const vibe = await browser.launch({ headless: true });
61
+ ```
62
+
63
+ | Option | Type | Default | Description |
64
+ |--------|------|---------|-------------|
65
+ | `headless` | boolean | `false` | Run without visible window |
66
+
67
+ ### vibe.go(url)
68
+
69
+ Navigate to a URL.
70
+
71
+ ```javascript
72
+ await vibe.go('https://example.com');
73
+ ```
74
+
75
+ ### vibe.find(selector, options?)
76
+
77
+ Find an element by CSS selector.
78
+
79
+ ```javascript
80
+ const button = await vibe.find('button.submit');
81
+ ```
82
+
83
+ | Option | Type | Default | Description |
84
+ |--------|------|---------|-------------|
85
+ | `timeout` | number | `30000` | Max wait time in ms |
86
+
87
+ ### vibe.screenshot()
88
+
89
+ Capture a screenshot. Returns a `Buffer` (PNG).
90
+
91
+ ```javascript
92
+ const png = await vibe.screenshot();
93
+ ```
94
+
95
+ ### vibe.quit()
96
+
97
+ Close the browser session.
98
+
99
+ ```javascript
100
+ await vibe.quit();
101
+ ```
102
+
103
+ ### element.click(options?)
104
+
105
+ Click the element. Waits for element to be visible, stable, and enabled.
106
+
107
+ ```javascript
108
+ await element.click();
109
+ ```
110
+
111
+ | Option | Type | Default | Description |
112
+ |--------|------|---------|-------------|
113
+ | `timeout` | number | `30000` | Max wait time in ms |
114
+
115
+ ### element.type(text, options?)
116
+
117
+ Type text into the element. Waits for element to be visible, stable, enabled, and editable.
118
+
119
+ ```javascript
120
+ await element.type('hello@example.com');
17
121
  ```
18
122
 
123
+ | Option | Type | Default | Description |
124
+ |--------|------|---------|-------------|
125
+ | `timeout` | number | `30000` | Max wait time in ms |
126
+
127
+ ### element.text()
128
+
129
+ Get the element's text content.
130
+
131
+ ```javascript
132
+ const text = await element.text();
133
+ ```
134
+
135
+ ### element.getAttribute(name)
136
+
137
+ Get an attribute value.
138
+
139
+ ```javascript
140
+ const testId = await element.getAttribute('data-testid');
141
+ ```
142
+
143
+ ### element.boundingBox()
144
+
145
+ Get the element's position and size. Returns `{x, y, width, height}`.
146
+
147
+ ```javascript
148
+ const box = await element.boundingBox();
149
+ ```
150
+
151
+ ## Environment Variables
152
+
153
+ | Variable | Description |
154
+ |----------|-------------|
155
+ | `VIBIUM_SKIP_BROWSER_DOWNLOAD` | Set to `1` to skip Chrome download on install |
156
+
157
+ ## Claude Code / MCP
158
+
159
+ Add Vibium to Claude Code:
160
+
161
+ ```bash
162
+ claude mcp add vibium -- npx vibium
163
+ ```
164
+
165
+ ### MCP Tools
166
+
167
+ #### browser_launch
168
+
169
+ Start a browser session.
170
+
171
+ | Parameter | Type | Default | Description |
172
+ |-----------|------|---------|-------------|
173
+ | `headless` | boolean | `false` | Run without visible window |
174
+
175
+ #### browser_navigate
176
+
177
+ Navigate to a URL.
178
+
179
+ | Parameter | Type | Required | Description |
180
+ |-----------|------|----------|-------------|
181
+ | `url` | string | yes | The URL to navigate to |
182
+
183
+ #### browser_click
184
+
185
+ Click an element. Waits for element to be visible, stable, and enabled.
186
+
187
+ | Parameter | Type | Required | Description |
188
+ |-----------|------|----------|-------------|
189
+ | `selector` | string | yes | CSS selector |
190
+
191
+ #### browser_type
192
+
193
+ Type text into an element. Waits for element to be visible, stable, enabled, and editable.
194
+
195
+ | Parameter | Type | Required | Description |
196
+ |-----------|------|----------|-------------|
197
+ | `selector` | string | yes | CSS selector |
198
+ | `text` | string | yes | Text to type |
199
+
200
+ #### browser_screenshot
201
+
202
+ Capture a screenshot.
203
+
204
+ | Parameter | Type | Required | Description |
205
+ |-----------|------|----------|-------------|
206
+ | `filename` | string | no | Save to file (e.g., screenshot.png) |
207
+
208
+ #### browser_find
209
+
210
+ Find an element and return its info (tag, text, bounding box).
211
+
212
+ | Parameter | Type | Required | Description |
213
+ |-----------|------|----------|-------------|
214
+ | `selector` | string | yes | CSS selector |
215
+
216
+ #### browser_quit
217
+
218
+ Close the browser session.
219
+
220
+ ## Links
221
+
222
+ - [GitHub / Documentation](https://github.com/VibiumDev/vibium)
223
+ - [Website](https://vibium.com)
224
+
19
225
  ## License
20
226
 
21
- MIT
227
+ Apache-2.0
package/bin.js ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ // Find clicker binary from platform package and run `clicker mcp`
3
+
4
+ const { execFileSync } = require('child_process');
5
+ const path = require('path');
6
+ const os = require('os');
7
+
8
+ function getClickerPath() {
9
+ const platform = os.platform();
10
+ const arch = os.arch() === 'x64' ? 'x64' : 'arm64';
11
+ const packageName = `@vibium/${platform}-${arch}`;
12
+ const binaryName = platform === 'win32' ? 'clicker.exe' : 'clicker';
13
+
14
+ try {
15
+ const packagePath = require.resolve(`${packageName}/package.json`);
16
+ return path.join(path.dirname(packagePath), 'bin', binaryName);
17
+ } catch {
18
+ console.error(`Could not find clicker binary for ${platform}-${arch}`);
19
+ process.exit(1);
20
+ }
21
+ }
22
+
23
+ const clickerPath = getClickerPath();
24
+ execFileSync(clickerPath, ['mcp'], { stdio: 'inherit' });
@@ -0,0 +1,198 @@
1
+ interface BiDiEvent {
2
+ method: string;
3
+ params: Record<string, unknown>;
4
+ }
5
+
6
+ type EventHandler = (event: BiDiEvent) => void;
7
+ declare class BiDiClient {
8
+ private connection;
9
+ private nextId;
10
+ private pendingCommands;
11
+ private eventHandler;
12
+ private constructor();
13
+ static connect(url: string): Promise<BiDiClient>;
14
+ private handleResponse;
15
+ private handleEvent;
16
+ onEvent(handler: EventHandler): void;
17
+ send<T = unknown>(method: string, params?: Record<string, unknown>): Promise<T>;
18
+ close(): Promise<void>;
19
+ }
20
+
21
+ interface ClickerProcessOptions {
22
+ port?: number;
23
+ headless?: boolean;
24
+ executablePath?: string;
25
+ }
26
+ declare class ClickerProcess {
27
+ private process;
28
+ private _port;
29
+ private _stopped;
30
+ private constructor();
31
+ get port(): number;
32
+ static start(options?: ClickerProcessOptions): Promise<ClickerProcess>;
33
+ stop(): Promise<void>;
34
+ }
35
+
36
+ interface BoundingBox {
37
+ x: number;
38
+ y: number;
39
+ width: number;
40
+ height: number;
41
+ }
42
+ interface ElementInfo {
43
+ tag: string;
44
+ text: string;
45
+ box: BoundingBox;
46
+ }
47
+ interface ActionOptions {
48
+ /** Timeout in milliseconds for actionability checks. Default: 30000 */
49
+ timeout?: number;
50
+ }
51
+ declare class Element {
52
+ private client;
53
+ private context;
54
+ private selector;
55
+ readonly info: ElementInfo;
56
+ constructor(client: BiDiClient, context: string, selector: string, info: ElementInfo);
57
+ /**
58
+ * Click the element.
59
+ * Waits for element to be visible, stable, receive events, and enabled.
60
+ */
61
+ click(options?: ActionOptions): Promise<void>;
62
+ /**
63
+ * Type text into the element.
64
+ * Waits for element to be visible, stable, receive events, enabled, and editable.
65
+ */
66
+ type(text: string, options?: ActionOptions): Promise<void>;
67
+ text(): Promise<string>;
68
+ getAttribute(name: string): Promise<string | null>;
69
+ boundingBox(): Promise<BoundingBox>;
70
+ private getCenter;
71
+ }
72
+
73
+ interface FindOptions {
74
+ /** Timeout in milliseconds to wait for element. Default: 30000 */
75
+ timeout?: number;
76
+ }
77
+ declare class Vibe {
78
+ private client;
79
+ private process;
80
+ private context;
81
+ constructor(client: BiDiClient, process: ClickerProcess | null);
82
+ private getContext;
83
+ go(url: string): Promise<void>;
84
+ screenshot(): Promise<Buffer>;
85
+ /**
86
+ * Execute JavaScript in the page context.
87
+ */
88
+ evaluate<T = unknown>(script: string): Promise<T>;
89
+ /**
90
+ * Find an element by CSS selector.
91
+ * Waits for element to exist before returning.
92
+ */
93
+ find(selector: string, options?: FindOptions): Promise<Element>;
94
+ quit(): Promise<void>;
95
+ }
96
+
97
+ interface LaunchOptions$1 {
98
+ headless?: boolean;
99
+ port?: number;
100
+ executablePath?: string;
101
+ }
102
+ declare const browser: {
103
+ launch(options?: LaunchOptions$1): Promise<Vibe>;
104
+ };
105
+
106
+ declare class SyncBridge {
107
+ private worker;
108
+ private signal;
109
+ private commandId;
110
+ private terminated;
111
+ private constructor();
112
+ static create(): SyncBridge;
113
+ call<T = unknown>(method: string, args?: unknown[]): T;
114
+ tryQuit(): void;
115
+ terminate(): void;
116
+ }
117
+
118
+ declare class ElementSync {
119
+ private bridge;
120
+ private elementId;
121
+ readonly info: ElementInfo;
122
+ constructor(bridge: SyncBridge, elementId: number, info: ElementInfo);
123
+ /**
124
+ * Click the element.
125
+ * Waits for element to be visible, stable, receive events, and enabled.
126
+ */
127
+ click(options?: ActionOptions): void;
128
+ /**
129
+ * Type text into the element.
130
+ * Waits for element to be visible, stable, receive events, enabled, and editable.
131
+ */
132
+ type(text: string, options?: ActionOptions): void;
133
+ text(): string;
134
+ getAttribute(name: string): string | null;
135
+ boundingBox(): BoundingBox;
136
+ }
137
+
138
+ declare class VibeSync {
139
+ private bridge;
140
+ constructor(bridge: SyncBridge);
141
+ go(url: string): void;
142
+ screenshot(): Buffer;
143
+ /**
144
+ * Execute JavaScript in the page context.
145
+ */
146
+ evaluate<T = unknown>(script: string): T;
147
+ /**
148
+ * Find an element by CSS selector.
149
+ * Waits for element to exist before returning.
150
+ */
151
+ find(selector: string, options?: FindOptions): ElementSync;
152
+ quit(): void;
153
+ }
154
+
155
+ interface LaunchOptions {
156
+ headless?: boolean;
157
+ }
158
+ declare const browserSync: {
159
+ launch(options?: LaunchOptions): VibeSync;
160
+ };
161
+
162
+ /**
163
+ * Custom error types for the Vibium client library.
164
+ */
165
+ /**
166
+ * ConnectionError is thrown when connecting to the browser fails.
167
+ */
168
+ declare class ConnectionError extends Error {
169
+ url: string;
170
+ cause?: Error | undefined;
171
+ constructor(url: string, cause?: Error | undefined);
172
+ }
173
+ /**
174
+ * TimeoutError is thrown when a wait operation times out.
175
+ */
176
+ declare class TimeoutError extends Error {
177
+ selector: string;
178
+ timeout: number;
179
+ reason?: string | undefined;
180
+ constructor(selector: string, timeout: number, reason?: string | undefined);
181
+ }
182
+ /**
183
+ * ElementNotFoundError is thrown when a selector matches no elements.
184
+ */
185
+ declare class ElementNotFoundError extends Error {
186
+ selector: string;
187
+ constructor(selector: string);
188
+ }
189
+ /**
190
+ * BrowserCrashedError is thrown when the browser process dies unexpectedly.
191
+ */
192
+ declare class BrowserCrashedError extends Error {
193
+ exitCode: number;
194
+ output?: string | undefined;
195
+ constructor(exitCode: number, output?: string | undefined);
196
+ }
197
+
198
+ export { type ActionOptions, type BoundingBox, BrowserCrashedError, ConnectionError, Element, type ElementInfo, ElementNotFoundError, ElementSync, type FindOptions, TimeoutError, Vibe, VibeSync, browser, browserSync };
@@ -0,0 +1,198 @@
1
+ interface BiDiEvent {
2
+ method: string;
3
+ params: Record<string, unknown>;
4
+ }
5
+
6
+ type EventHandler = (event: BiDiEvent) => void;
7
+ declare class BiDiClient {
8
+ private connection;
9
+ private nextId;
10
+ private pendingCommands;
11
+ private eventHandler;
12
+ private constructor();
13
+ static connect(url: string): Promise<BiDiClient>;
14
+ private handleResponse;
15
+ private handleEvent;
16
+ onEvent(handler: EventHandler): void;
17
+ send<T = unknown>(method: string, params?: Record<string, unknown>): Promise<T>;
18
+ close(): Promise<void>;
19
+ }
20
+
21
+ interface ClickerProcessOptions {
22
+ port?: number;
23
+ headless?: boolean;
24
+ executablePath?: string;
25
+ }
26
+ declare class ClickerProcess {
27
+ private process;
28
+ private _port;
29
+ private _stopped;
30
+ private constructor();
31
+ get port(): number;
32
+ static start(options?: ClickerProcessOptions): Promise<ClickerProcess>;
33
+ stop(): Promise<void>;
34
+ }
35
+
36
+ interface BoundingBox {
37
+ x: number;
38
+ y: number;
39
+ width: number;
40
+ height: number;
41
+ }
42
+ interface ElementInfo {
43
+ tag: string;
44
+ text: string;
45
+ box: BoundingBox;
46
+ }
47
+ interface ActionOptions {
48
+ /** Timeout in milliseconds for actionability checks. Default: 30000 */
49
+ timeout?: number;
50
+ }
51
+ declare class Element {
52
+ private client;
53
+ private context;
54
+ private selector;
55
+ readonly info: ElementInfo;
56
+ constructor(client: BiDiClient, context: string, selector: string, info: ElementInfo);
57
+ /**
58
+ * Click the element.
59
+ * Waits for element to be visible, stable, receive events, and enabled.
60
+ */
61
+ click(options?: ActionOptions): Promise<void>;
62
+ /**
63
+ * Type text into the element.
64
+ * Waits for element to be visible, stable, receive events, enabled, and editable.
65
+ */
66
+ type(text: string, options?: ActionOptions): Promise<void>;
67
+ text(): Promise<string>;
68
+ getAttribute(name: string): Promise<string | null>;
69
+ boundingBox(): Promise<BoundingBox>;
70
+ private getCenter;
71
+ }
72
+
73
+ interface FindOptions {
74
+ /** Timeout in milliseconds to wait for element. Default: 30000 */
75
+ timeout?: number;
76
+ }
77
+ declare class Vibe {
78
+ private client;
79
+ private process;
80
+ private context;
81
+ constructor(client: BiDiClient, process: ClickerProcess | null);
82
+ private getContext;
83
+ go(url: string): Promise<void>;
84
+ screenshot(): Promise<Buffer>;
85
+ /**
86
+ * Execute JavaScript in the page context.
87
+ */
88
+ evaluate<T = unknown>(script: string): Promise<T>;
89
+ /**
90
+ * Find an element by CSS selector.
91
+ * Waits for element to exist before returning.
92
+ */
93
+ find(selector: string, options?: FindOptions): Promise<Element>;
94
+ quit(): Promise<void>;
95
+ }
96
+
97
+ interface LaunchOptions$1 {
98
+ headless?: boolean;
99
+ port?: number;
100
+ executablePath?: string;
101
+ }
102
+ declare const browser: {
103
+ launch(options?: LaunchOptions$1): Promise<Vibe>;
104
+ };
105
+
106
+ declare class SyncBridge {
107
+ private worker;
108
+ private signal;
109
+ private commandId;
110
+ private terminated;
111
+ private constructor();
112
+ static create(): SyncBridge;
113
+ call<T = unknown>(method: string, args?: unknown[]): T;
114
+ tryQuit(): void;
115
+ terminate(): void;
116
+ }
117
+
118
+ declare class ElementSync {
119
+ private bridge;
120
+ private elementId;
121
+ readonly info: ElementInfo;
122
+ constructor(bridge: SyncBridge, elementId: number, info: ElementInfo);
123
+ /**
124
+ * Click the element.
125
+ * Waits for element to be visible, stable, receive events, and enabled.
126
+ */
127
+ click(options?: ActionOptions): void;
128
+ /**
129
+ * Type text into the element.
130
+ * Waits for element to be visible, stable, receive events, enabled, and editable.
131
+ */
132
+ type(text: string, options?: ActionOptions): void;
133
+ text(): string;
134
+ getAttribute(name: string): string | null;
135
+ boundingBox(): BoundingBox;
136
+ }
137
+
138
+ declare class VibeSync {
139
+ private bridge;
140
+ constructor(bridge: SyncBridge);
141
+ go(url: string): void;
142
+ screenshot(): Buffer;
143
+ /**
144
+ * Execute JavaScript in the page context.
145
+ */
146
+ evaluate<T = unknown>(script: string): T;
147
+ /**
148
+ * Find an element by CSS selector.
149
+ * Waits for element to exist before returning.
150
+ */
151
+ find(selector: string, options?: FindOptions): ElementSync;
152
+ quit(): void;
153
+ }
154
+
155
+ interface LaunchOptions {
156
+ headless?: boolean;
157
+ }
158
+ declare const browserSync: {
159
+ launch(options?: LaunchOptions): VibeSync;
160
+ };
161
+
162
+ /**
163
+ * Custom error types for the Vibium client library.
164
+ */
165
+ /**
166
+ * ConnectionError is thrown when connecting to the browser fails.
167
+ */
168
+ declare class ConnectionError extends Error {
169
+ url: string;
170
+ cause?: Error | undefined;
171
+ constructor(url: string, cause?: Error | undefined);
172
+ }
173
+ /**
174
+ * TimeoutError is thrown when a wait operation times out.
175
+ */
176
+ declare class TimeoutError extends Error {
177
+ selector: string;
178
+ timeout: number;
179
+ reason?: string | undefined;
180
+ constructor(selector: string, timeout: number, reason?: string | undefined);
181
+ }
182
+ /**
183
+ * ElementNotFoundError is thrown when a selector matches no elements.
184
+ */
185
+ declare class ElementNotFoundError extends Error {
186
+ selector: string;
187
+ constructor(selector: string);
188
+ }
189
+ /**
190
+ * BrowserCrashedError is thrown when the browser process dies unexpectedly.
191
+ */
192
+ declare class BrowserCrashedError extends Error {
193
+ exitCode: number;
194
+ output?: string | undefined;
195
+ constructor(exitCode: number, output?: string | undefined);
196
+ }
197
+
198
+ export { type ActionOptions, type BoundingBox, BrowserCrashedError, ConnectionError, Element, type ElementInfo, ElementNotFoundError, ElementSync, type FindOptions, TimeoutError, Vibe, VibeSync, browser, browserSync };