poltertab 1.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.
- package/README.md +303 -0
- package/assets/claude-md-snippet.md +17 -0
- package/bin/poltertab.js +32 -0
- package/bin/setup.js +216 -0
- package/mcp-server/index.js +1096 -0
- package/package.json +48 -0
- package/skills/browser-navigation-strategy/SKILL.md +96 -0
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "poltertab",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Let any AI assistant drive and scrape your existing Chrome profile — no headless browser, no complex setup.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"poltertab": "./bin/poltertab.js"
|
|
7
|
+
},
|
|
8
|
+
"main": "mcp-server/index.js",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "node mcp-server/test/run.js && node test/setup.test.js",
|
|
11
|
+
"setup": "node bin/poltertab.js setup",
|
|
12
|
+
"version": "node scripts/sync-manifest-version.js && git add chrome-extension/manifest.json"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"bin/",
|
|
16
|
+
"mcp-server/",
|
|
17
|
+
"skills/",
|
|
18
|
+
"assets/",
|
|
19
|
+
"!mcp-server/test/",
|
|
20
|
+
"!mcp-server/test-client.js",
|
|
21
|
+
"!mcp-server/downloads/",
|
|
22
|
+
"!mcp-server/navigation_memory/"
|
|
23
|
+
],
|
|
24
|
+
"keywords": [
|
|
25
|
+
"mcp",
|
|
26
|
+
"chrome",
|
|
27
|
+
"browser-automation",
|
|
28
|
+
"claude",
|
|
29
|
+
"model-context-protocol",
|
|
30
|
+
"browser-control"
|
|
31
|
+
],
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/abhinav162/poltertab.git"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://github.com/abhinav162/poltertab#readme",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/abhinav162/poltertab/issues"
|
|
39
|
+
},
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=18"
|
|
42
|
+
},
|
|
43
|
+
"license": "ISC",
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
46
|
+
"ws": "^8.21.3"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: browser-navigation-strategy
|
|
3
|
+
description: Use when driving a real browser with PolterTab's browser_* tools — navigating, scraping, or clicking through a site whose DOM is virtualized, obfuscated, shadow-rooted, or iframe-sandboxed, and selectors keep going stale.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Browser Navigation Strategy
|
|
7
|
+
|
|
8
|
+
PolterTab drives the user's real Chrome profile. Sessions are already logged in,
|
|
9
|
+
and every action happens in a window the user can see. That makes it powerful and
|
|
10
|
+
unforgiving: a wrong click lands on a real account.
|
|
11
|
+
|
|
12
|
+
## Read the page before you touch it
|
|
13
|
+
|
|
14
|
+
`browser_snapshot` is the first call on any unfamiliar page. It returns visible,
|
|
15
|
+
interactive elements with `@e1`-style refs, and it descends into shadow roots and
|
|
16
|
+
child frames — so what it shows you is the page as it really is, not just the
|
|
17
|
+
top-level light DOM.
|
|
18
|
+
|
|
19
|
+
Never guess a selector from a URL or a screenshot. Snapshot, then act on what
|
|
20
|
+
came back.
|
|
21
|
+
|
|
22
|
+
## Prefer the network over the DOM
|
|
23
|
+
|
|
24
|
+
On a virtualized list (LinkedIn, most infinite feeds), the DOM holds only the
|
|
25
|
+
rows currently on screen, under class names that change between deploys. Scraping
|
|
26
|
+
it yields a fraction of the data and breaks next week.
|
|
27
|
+
|
|
28
|
+
The reliable path:
|
|
29
|
+
|
|
30
|
+
1. `browser_set_intercept_patterns` if the site uses endpoints outside the
|
|
31
|
+
defaults (`graphql`, `/api/`, `voyager`, `feed`).
|
|
32
|
+
2. `browser_smart_scroll` to trigger lazy loading. It yields until new requests
|
|
33
|
+
land, so you do not have to guess a wait.
|
|
34
|
+
3. `browser_get_network_state` to read the structured JSON the page itself
|
|
35
|
+
received.
|
|
36
|
+
|
|
37
|
+
Pass `output_file` on `browser_get_network_state` for anything large. The payload
|
|
38
|
+
goes to disk and you get a summary — a 4 MB GraphQL response does not belong in
|
|
39
|
+
the context window.
|
|
40
|
+
|
|
41
|
+
## Shadow DOM, iframes, and late modals
|
|
42
|
+
|
|
43
|
+
PolterTab handles these without special flags, which is worth knowing so you do
|
|
44
|
+
not work around problems it already solves:
|
|
45
|
+
|
|
46
|
+
- **Shadow roots** — including closed ones — are pierced automatically. A
|
|
47
|
+
selector that matches inside a web component just works.
|
|
48
|
+
- **Child frames** are searched in parallel when the top frame misses, so an
|
|
49
|
+
element inside a sandboxed iframe is reachable by plain selector.
|
|
50
|
+
- **Late-rendering elements** get retried for ~3s. A modal that mounts a beat
|
|
51
|
+
after the click that opened it does not need a manual wait.
|
|
52
|
+
|
|
53
|
+
If an element genuinely is not there, you get `Element not found` after the
|
|
54
|
+
retry window. Treat that as "not on this page", not "try again immediately".
|
|
55
|
+
|
|
56
|
+
## Selectors, in order of durability
|
|
57
|
+
|
|
58
|
+
1. `#id` and `[data-testid]` — survive redesigns.
|
|
59
|
+
2. `[aria-label="..."]`, `[role=...]`, `[placeholder="..."]` — semantic, stable.
|
|
60
|
+
3. Exact visible text — PolterTab matches it across shadow boundaries.
|
|
61
|
+
4. Structural CSS (`div > div:nth-child(3)`) — last resort, expect breakage.
|
|
62
|
+
|
|
63
|
+
Long generated class chains (`.css-1x2y3z4`) are the worst of both worlds:
|
|
64
|
+
brittle and unreadable. Reach for a `@e` ref from the last snapshot instead.
|
|
65
|
+
|
|
66
|
+
## Carry knowledge between sessions
|
|
67
|
+
|
|
68
|
+
`browser_get_site_memory(hostname)` at the start of work on a site, and
|
|
69
|
+
`browser_save_site_memory` the moment you solve something non-obvious — a cookie
|
|
70
|
+
wall that intercepts the first click, a required query parameter, the shape of a
|
|
71
|
+
GraphQL response worth reusing.
|
|
72
|
+
|
|
73
|
+
The point is to not rediscover the same obstacle next week. Save the obstacle and
|
|
74
|
+
the fix together; a note saying "this page is tricky" helps nobody.
|
|
75
|
+
|
|
76
|
+
## Multiple tabs
|
|
77
|
+
|
|
78
|
+
`browser_session_create` gives a named tab you can return to. Every page-facing
|
|
79
|
+
tool takes `session` (or `tabId`) to target it. Omit both and PolterTab uses the
|
|
80
|
+
last tab it navigated, falling back to the active tab — fine for single-track
|
|
81
|
+
work, ambiguous the moment two flows interleave. Name your sessions when running
|
|
82
|
+
more than one.
|
|
83
|
+
|
|
84
|
+
Close what you opened with `browser_session_close`.
|
|
85
|
+
|
|
86
|
+
## Pitfalls
|
|
87
|
+
|
|
88
|
+
- Do not use `browser_get_text` or `browser_scrape` on virtualized lists. Use
|
|
89
|
+
`browser_smart_scroll` then `browser_get_network_state`.
|
|
90
|
+
- Do not invent intercept patterns. Check the defaults, then set only what the
|
|
91
|
+
site actually needs.
|
|
92
|
+
- Do not paste large scraped payloads into the conversation. Use `output_file`.
|
|
93
|
+
- Do not retry a failed selector unchanged. The retry already happened inside
|
|
94
|
+
the tool — snapshot again and find out what the page really contains.
|
|
95
|
+
- This is the user's live browser. Anything that sends, buys, deletes, or posts
|
|
96
|
+
gets confirmed with them first.
|