grab 0.0.98 → 0.1.0-beta.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.
- package/README.md +114 -372
- package/dist/chunk-DIAOCH5J.cjs +88 -0
- package/dist/chunk-VXZ5VMRT.js +88 -0
- package/dist/cli.cjs +1 -1137
- package/dist/core/index.cjs +1 -1
- package/dist/core/index.d.cts +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +1 -1
- package/dist/{index-r1odQUH0.d.cts → index-BdKhAk4Q.d.cts} +79 -28
- package/dist/{index-r1odQUH0.d.ts → index-BdKhAk4Q.d.ts} +79 -28
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +15 -3
- package/dist/index.d.ts +15 -3
- package/dist/index.global.js +25 -25
- package/dist/index.js +2 -2
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/dist/chunk-D2FWI6AP.js +0 -88
- package/dist/chunk-H4U7EPBM.cjs +0 -88
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ It makes tools like Cursor, Claude Code, Copilot run up to [**3× faster**](http
|
|
|
19
19
|
Run this command to install React Grab into your project. Ensure you are running at project root (e.g. where the `next.config.ts` or `vite.config.ts` file is located).
|
|
20
20
|
|
|
21
21
|
```html
|
|
22
|
-
npx grab@latest init
|
|
22
|
+
npx -y grab@latest init
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
## Usage
|
|
@@ -136,430 +136,172 @@ if (process.env.NODE_ENV === "development") {
|
|
|
136
136
|
}
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
-
##
|
|
139
|
+
## MCP Server
|
|
140
140
|
|
|
141
|
-
React Grab
|
|
141
|
+
React Grab includes an MCP (Model Context Protocol) server that gives AI coding agents direct access to your browser. This enables agents to navigate, click, fill forms, and take screenshots.
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
### Setup
|
|
144
144
|
|
|
145
|
-
|
|
145
|
+
Run during project init:
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
#### Server Setup
|
|
151
|
-
|
|
152
|
-
The server runs on port `4567` and interfaces with the Claude Agent SDK. Add to your `package.json`:
|
|
153
|
-
|
|
154
|
-
```json
|
|
155
|
-
{
|
|
156
|
-
"scripts": {
|
|
157
|
-
"dev": "npx @react-grab/claude-code@latest && next dev"
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
#### Client Setup
|
|
163
|
-
|
|
164
|
-
```html
|
|
165
|
-
<script src="//unpkg.com/grab/dist/index.global.js"></script>
|
|
166
|
-
<!-- add this in the <head> -->
|
|
167
|
-
<script src="//unpkg.com/@react-grab/claude-code/dist/client.global.js"></script>
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
Or using Next.js `Script` component in your `app/layout.tsx`:
|
|
171
|
-
|
|
172
|
-
```jsx
|
|
173
|
-
import Script from "next/script";
|
|
174
|
-
|
|
175
|
-
export default function RootLayout({ children }) {
|
|
176
|
-
return (
|
|
177
|
-
<html>
|
|
178
|
-
<head>
|
|
179
|
-
{process.env.NODE_ENV === "development" && (
|
|
180
|
-
<>
|
|
181
|
-
<Script
|
|
182
|
-
src="//unpkg.com/grab/dist/index.global.js"
|
|
183
|
-
strategy="beforeInteractive"
|
|
184
|
-
/>
|
|
185
|
-
<Script
|
|
186
|
-
src="//unpkg.com/@react-grab/claude-code/dist/client.global.js"
|
|
187
|
-
strategy="lazyOnload"
|
|
188
|
-
/>
|
|
189
|
-
</>
|
|
190
|
-
)}
|
|
191
|
-
</head>
|
|
192
|
-
<body>{children}</body>
|
|
193
|
-
</html>
|
|
194
|
-
);
|
|
195
|
-
}
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
</details>
|
|
199
|
-
|
|
200
|
-
<details>
|
|
201
|
-
<summary><strong>Cursor CLI</strong></summary>
|
|
202
|
-
|
|
203
|
-
You must have the [`cursor-agent` CLI](https://cursor.com/docs/cli/overview) installed.
|
|
204
|
-
|
|
205
|
-
#### Server Setup
|
|
206
|
-
|
|
207
|
-
The server runs on port `5567` and interfaces with the `cursor-agent` CLI. Add to your `package.json`:
|
|
208
|
-
|
|
209
|
-
```json
|
|
210
|
-
{
|
|
211
|
-
"scripts": {
|
|
212
|
-
"dev": "npx @react-grab/cursor@latest && next dev"
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
#### Client Setup
|
|
218
|
-
|
|
219
|
-
```html
|
|
220
|
-
<script src="//unpkg.com/grab/dist/index.global.js"></script>
|
|
221
|
-
<!-- add this in the <head> -->
|
|
222
|
-
<script src="//unpkg.com/@react-grab/cursor/dist/client.global.js"></script>
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
Or using Next.js `Script` component in your `app/layout.tsx`:
|
|
226
|
-
|
|
227
|
-
```jsx
|
|
228
|
-
import Script from "next/script";
|
|
229
|
-
|
|
230
|
-
export default function RootLayout({ children }) {
|
|
231
|
-
return (
|
|
232
|
-
<html>
|
|
233
|
-
<head>
|
|
234
|
-
{process.env.NODE_ENV === "development" && (
|
|
235
|
-
<>
|
|
236
|
-
<Script
|
|
237
|
-
src="//unpkg.com/grab/dist/index.global.js"
|
|
238
|
-
strategy="beforeInteractive"
|
|
239
|
-
/>
|
|
240
|
-
<Script
|
|
241
|
-
src="//unpkg.com/@react-grab/cursor/dist/client.global.js"
|
|
242
|
-
strategy="lazyOnload"
|
|
243
|
-
/>
|
|
244
|
-
</>
|
|
245
|
-
)}
|
|
246
|
-
</head>
|
|
247
|
-
<body>{children}</body>
|
|
248
|
-
</html>
|
|
249
|
-
);
|
|
250
|
-
}
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
</details>
|
|
254
|
-
|
|
255
|
-
<details>
|
|
256
|
-
<summary><strong>OpenCode</strong></summary>
|
|
257
|
-
|
|
258
|
-
#### Server Setup
|
|
259
|
-
|
|
260
|
-
The server runs on port `6567` and interfaces with the OpenCode CLI. Add to your `package.json`:
|
|
261
|
-
|
|
262
|
-
```json
|
|
263
|
-
{
|
|
264
|
-
"scripts": {
|
|
265
|
-
"dev": "npx @react-grab/opencode@latest && next dev"
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
> **Note:** You must have [OpenCode](https://opencode.ai) installed (`npm i -g opencode-ai@latest`).
|
|
271
|
-
|
|
272
|
-
#### Client Setup
|
|
273
|
-
|
|
274
|
-
```html
|
|
275
|
-
<script src="//unpkg.com/grab/dist/index.global.js"></script>
|
|
276
|
-
<!-- add this in the <head> -->
|
|
277
|
-
<script src="//unpkg.com/@react-grab/opencode/dist/client.global.js"></script>
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
Or using Next.js `Script` component in your `app/layout.tsx`:
|
|
281
|
-
|
|
282
|
-
```jsx
|
|
283
|
-
import Script from "next/script";
|
|
284
|
-
|
|
285
|
-
export default function RootLayout({ children }) {
|
|
286
|
-
return (
|
|
287
|
-
<html>
|
|
288
|
-
<head>
|
|
289
|
-
{process.env.NODE_ENV === "development" && (
|
|
290
|
-
<>
|
|
291
|
-
<Script
|
|
292
|
-
src="//unpkg.com/grab/dist/index.global.js"
|
|
293
|
-
strategy="beforeInteractive"
|
|
294
|
-
/>
|
|
295
|
-
<Script
|
|
296
|
-
src="//unpkg.com/@react-grab/opencode/dist/client.global.js"
|
|
297
|
-
strategy="lazyOnload"
|
|
298
|
-
/>
|
|
299
|
-
</>
|
|
300
|
-
)}
|
|
301
|
-
</head>
|
|
302
|
-
<body>{children}</body>
|
|
303
|
-
</html>
|
|
304
|
-
);
|
|
305
|
-
}
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
</details>
|
|
309
|
-
|
|
310
|
-
<details>
|
|
311
|
-
<summary><strong>Codex</strong></summary>
|
|
312
|
-
|
|
313
|
-
#### Server Setup
|
|
314
|
-
|
|
315
|
-
The server runs on port `7567` and interfaces with the OpenAI Codex SDK. Add to your `package.json`:
|
|
316
|
-
|
|
317
|
-
```json
|
|
318
|
-
{
|
|
319
|
-
"scripts": {
|
|
320
|
-
"dev": "npx @react-grab/codex@latest && next dev"
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
> **Note:** You must have [Codex](https://github.com/openai/codex) installed (`npm i -g @openai/codex`).
|
|
326
|
-
|
|
327
|
-
#### Client Setup
|
|
328
|
-
|
|
329
|
-
```html
|
|
330
|
-
<script src="//unpkg.com/grab/dist/index.global.js"></script>
|
|
331
|
-
<!-- add this in the <head> -->
|
|
332
|
-
<script src="//unpkg.com/@react-grab/codex/dist/client.global.js"></script>
|
|
147
|
+
```bash
|
|
148
|
+
npx -y grab@latest init
|
|
149
|
+
# When prompted, choose to add the MCP server
|
|
333
150
|
```
|
|
334
151
|
|
|
335
|
-
Or
|
|
152
|
+
Or add it separately:
|
|
336
153
|
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
export default function RootLayout({ children }) {
|
|
341
|
-
return (
|
|
342
|
-
<html>
|
|
343
|
-
<head>
|
|
344
|
-
{process.env.NODE_ENV === "development" && (
|
|
345
|
-
<>
|
|
346
|
-
<Script
|
|
347
|
-
src="//unpkg.com/grab/dist/index.global.js"
|
|
348
|
-
strategy="beforeInteractive"
|
|
349
|
-
/>
|
|
350
|
-
<Script
|
|
351
|
-
src="//unpkg.com/@react-grab/codex/dist/client.global.js"
|
|
352
|
-
strategy="lazyOnload"
|
|
353
|
-
/>
|
|
354
|
-
</>
|
|
355
|
-
)}
|
|
356
|
-
</head>
|
|
357
|
-
<body>{children}</body>
|
|
358
|
-
</html>
|
|
359
|
-
);
|
|
360
|
-
}
|
|
154
|
+
```bash
|
|
155
|
+
npx -y grab@latest add mcp --client cursor
|
|
361
156
|
```
|
|
362
157
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
<details>
|
|
366
|
-
<summary><strong>Gemini</strong></summary>
|
|
158
|
+
Supported clients: `cursor`, `claude-code`, `vscode`, `opencode`, `codex`, `gemini-cli`, `windsurf`, `zed`, `droid`
|
|
367
159
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
The server runs on port `8567` and interfaces with the Gemini CLI. Add to your `package.json`:
|
|
160
|
+
Or add it manually to your `mcp.json` file:
|
|
371
161
|
|
|
372
162
|
```json
|
|
373
163
|
{
|
|
374
|
-
"
|
|
375
|
-
"
|
|
164
|
+
"mcpServers": {
|
|
165
|
+
"react-grab-browser": {
|
|
166
|
+
"command": "npx",
|
|
167
|
+
"args": ["-y", "@react-grab/cli", "browser", "mcp"]
|
|
168
|
+
}
|
|
376
169
|
}
|
|
377
170
|
}
|
|
378
171
|
```
|
|
379
172
|
|
|
380
|
-
|
|
173
|
+
### MCP Tools
|
|
381
174
|
|
|
382
|
-
|
|
175
|
+
Once configured, your agent has access to:
|
|
383
176
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
<!-- add this in the <head> -->
|
|
387
|
-
<script src="//unpkg.com/@react-grab/gemini/dist/client.global.js"></script>
|
|
388
|
-
```
|
|
177
|
+
- `browser_snapshot` - Get ARIA accessibility tree with element refs (e1, e2...)
|
|
178
|
+
- `browser_execute` - Run Playwright code with helpers like `ref('e1').click()`
|
|
389
179
|
|
|
390
|
-
|
|
180
|
+
## Skill
|
|
391
181
|
|
|
392
|
-
|
|
393
|
-
import Script from "next/script";
|
|
182
|
+
For agents that support skills (like Codex), install the `react-grab-browser` skill:
|
|
394
183
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
{process.env.NODE_ENV === "development" && (
|
|
400
|
-
<>
|
|
401
|
-
<Script
|
|
402
|
-
src="//unpkg.com/grab/dist/index.global.js"
|
|
403
|
-
strategy="beforeInteractive"
|
|
404
|
-
/>
|
|
405
|
-
<Script
|
|
406
|
-
src="//unpkg.com/@react-grab/gemini/dist/client.global.js"
|
|
407
|
-
strategy="lazyOnload"
|
|
408
|
-
/>
|
|
409
|
-
</>
|
|
410
|
-
)}
|
|
411
|
-
</head>
|
|
412
|
-
<body>{children}</body>
|
|
413
|
-
</html>
|
|
414
|
-
);
|
|
415
|
-
}
|
|
184
|
+
```bash
|
|
185
|
+
npx -y grab@latest add skill
|
|
186
|
+
# or
|
|
187
|
+
npx -y openskills install aidenybai/react-grab -y
|
|
416
188
|
```
|
|
417
189
|
|
|
418
|
-
|
|
190
|
+
The skill provides browser automation with Playwright using your real browser cookies. See the [skill documentation](https://github.com/aidenybai/react-grab/blob/main/skills/react-grab-browser/SKILL.md) for full details.
|
|
419
191
|
|
|
420
|
-
|
|
421
|
-
<summary><strong>Amp</strong></summary>
|
|
192
|
+
## Claude Plugin
|
|
422
193
|
|
|
423
|
-
|
|
194
|
+
React Grab includes a Claude plugin for Claude Code/Desktop. The plugin is located in `.claude-plugin/` and provides browser automation capabilities.
|
|
424
195
|
|
|
425
|
-
|
|
196
|
+
To use it, ensure the plugin files are present:
|
|
197
|
+
- `.claude-plugin/marketplace.json` - Plugin manifest
|
|
198
|
+
- `.claude/skills/react-grab-browser/` - Skill files (SKILL.md, EXAMPLES.md, REFERENCE.md)
|
|
426
199
|
|
|
427
|
-
|
|
428
|
-
{
|
|
429
|
-
"scripts": {
|
|
430
|
-
"dev": "npx @react-grab/amp@latest && next dev"
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
```
|
|
200
|
+
The plugin triggers on browser-related requests like "browse", "navigate to", "screenshot", "click on", "fill form", etc.
|
|
434
201
|
|
|
435
|
-
|
|
202
|
+
## Extending React Grab
|
|
436
203
|
|
|
437
|
-
|
|
204
|
+
React Grab uses a plugin system to extend functionality. Check out the [type definitions](https://github.com/aidenybai/react-grab/blob/main/packages/react-grab/src/types.ts) to see all available options.
|
|
438
205
|
|
|
439
|
-
|
|
440
|
-
<script src="//unpkg.com/grab/dist/index.global.js"></script>
|
|
441
|
-
<!-- add this in the <head> -->
|
|
442
|
-
<script src="//unpkg.com/@react-grab/amp/dist/client.global.js"></script>
|
|
443
|
-
```
|
|
206
|
+
#### Basic Usage
|
|
444
207
|
|
|
445
|
-
|
|
208
|
+
```typescript
|
|
209
|
+
import { init } from "grab/core";
|
|
446
210
|
|
|
447
|
-
|
|
448
|
-
import Script from "next/script";
|
|
211
|
+
const api = init();
|
|
449
212
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
<head>
|
|
454
|
-
{process.env.NODE_ENV === "development" && (
|
|
455
|
-
<>
|
|
456
|
-
<Script
|
|
457
|
-
src="//unpkg.com/grab/dist/index.global.js"
|
|
458
|
-
strategy="beforeInteractive"
|
|
459
|
-
/>
|
|
460
|
-
<Script
|
|
461
|
-
src="//unpkg.com/@react-grab/amp/dist/client.global.js"
|
|
462
|
-
strategy="lazyOnload"
|
|
463
|
-
/>
|
|
464
|
-
</>
|
|
465
|
-
)}
|
|
466
|
-
</head>
|
|
467
|
-
<body>{children}</body>
|
|
468
|
-
</html>
|
|
469
|
-
);
|
|
470
|
-
}
|
|
213
|
+
api.activate();
|
|
214
|
+
api.copyElement(document.querySelector(".my-element"));
|
|
215
|
+
console.log(api.getState());
|
|
471
216
|
```
|
|
472
217
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
<details>
|
|
476
|
-
<summary><strong>Factory Droid</strong></summary>
|
|
477
|
-
|
|
478
|
-
#### Server Setup
|
|
218
|
+
#### Lifecycle Hooks Plugin
|
|
479
219
|
|
|
480
|
-
|
|
220
|
+
Track element selections with analytics:
|
|
481
221
|
|
|
482
|
-
```
|
|
483
|
-
{
|
|
484
|
-
"
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
}
|
|
222
|
+
```typescript
|
|
223
|
+
api.registerPlugin({
|
|
224
|
+
name: "analytics",
|
|
225
|
+
hooks: {
|
|
226
|
+
onElementSelect: (element) => {
|
|
227
|
+
analytics.track("element_selected", { tagName: element.tagName });
|
|
228
|
+
},
|
|
229
|
+
onDragEnd: (elements, bounds) => {
|
|
230
|
+
analytics.track("drag_end", { count: elements.length, bounds });
|
|
231
|
+
},
|
|
232
|
+
onCopySuccess: (elements, content) => {
|
|
233
|
+
analytics.track("copy", { count: elements.length });
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
});
|
|
488
237
|
```
|
|
489
238
|
|
|
490
|
-
|
|
239
|
+
#### Context Menu Plugin
|
|
491
240
|
|
|
492
|
-
|
|
241
|
+
Add custom actions to the right-click menu:
|
|
493
242
|
|
|
494
|
-
```
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
243
|
+
```typescript
|
|
244
|
+
api.registerPlugin({
|
|
245
|
+
name: "custom-actions",
|
|
246
|
+
actions: [
|
|
247
|
+
{
|
|
248
|
+
id: "log-to-console",
|
|
249
|
+
label: "Log to Console",
|
|
250
|
+
onAction: ({ elements }) => console.dir(elements[0]),
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
});
|
|
498
254
|
```
|
|
499
255
|
|
|
500
|
-
|
|
256
|
+
#### Theme Plugin
|
|
501
257
|
|
|
502
|
-
|
|
503
|
-
import Script from "next/script";
|
|
258
|
+
Customize the UI appearance:
|
|
504
259
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
/>
|
|
515
|
-
<Script
|
|
516
|
-
src="//unpkg.com/@react-grab/droid/dist/client.global.js"
|
|
517
|
-
strategy="lazyOnload"
|
|
518
|
-
/>
|
|
519
|
-
</>
|
|
520
|
-
)}
|
|
521
|
-
</head>
|
|
522
|
-
<body>{children}</body>
|
|
523
|
-
</html>
|
|
524
|
-
);
|
|
525
|
-
}
|
|
260
|
+
```typescript
|
|
261
|
+
api.registerPlugin({
|
|
262
|
+
name: "theme",
|
|
263
|
+
theme: {
|
|
264
|
+
hue: 180, // shift colors (pink → cyan)
|
|
265
|
+
crosshair: { enabled: false },
|
|
266
|
+
elementLabel: { enabled: false },
|
|
267
|
+
},
|
|
268
|
+
});
|
|
526
269
|
```
|
|
527
270
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
## Extending React Grab
|
|
271
|
+
#### Agent Plugin
|
|
531
272
|
|
|
532
|
-
|
|
273
|
+
Create a custom agent that processes selected elements:
|
|
533
274
|
|
|
534
275
|
```typescript
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
276
|
+
api.registerPlugin({
|
|
277
|
+
name: "my-custom-agent",
|
|
278
|
+
actions: [
|
|
279
|
+
{
|
|
280
|
+
id: "custom-agent",
|
|
281
|
+
label: "Ask AI",
|
|
282
|
+
onAction: ({ enterPromptMode }) => enterPromptMode?.(),
|
|
283
|
+
agent: {
|
|
284
|
+
provider: {
|
|
285
|
+
async *send({ prompt, content }, signal) {
|
|
286
|
+
yield "Analyzing element...";
|
|
287
|
+
|
|
288
|
+
const response = await fetch("/api/ai", {
|
|
289
|
+
method: "POST",
|
|
290
|
+
headers: { "Content-Type": "application/json" },
|
|
291
|
+
body: JSON.stringify({ prompt, content }),
|
|
292
|
+
signal,
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
yield "Processing response...";
|
|
296
|
+
|
|
297
|
+
const result = await response.json();
|
|
298
|
+
yield `Done: ${result.message}`;
|
|
299
|
+
},
|
|
300
|
+
},
|
|
301
|
+
},
|
|
546
302
|
},
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
onElementSelect: (element) => {
|
|
550
|
-
console.log("Selected:", element);
|
|
551
|
-
},
|
|
552
|
-
onCopySuccess: (elements, content) => {
|
|
553
|
-
console.log("Copied to clipboard:", content);
|
|
554
|
-
},
|
|
555
|
-
onStateChange: (state) => {
|
|
556
|
-
console.log("Active:", state.isActive);
|
|
557
|
-
},
|
|
303
|
+
],
|
|
558
304
|
});
|
|
559
|
-
|
|
560
|
-
api.activate();
|
|
561
|
-
api.copyElement(document.querySelector(".my-element"));
|
|
562
|
-
console.log(api.getState());
|
|
563
305
|
```
|
|
564
306
|
|
|
565
307
|
## Resources & Contributing Back
|