.claude/skills/browser-script/SKILL.md
Create a browser automation script that bundles multi-step browser interactions into a single browser_run_code call. Use when: 'automate browser flow', 'create browser script', 'script this browser task', 'bundle browser steps', 'reduce browser tokens'.
npx skillsauth add m13v/social-autoposter browser-scriptInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Create self-contained JS scripts that run inside platform browser agents (linkedin-agent, reddit-agent, twitter-agent) via browser_run_code. Replaces 5-10 Claude browser tool calls with 2 calls (set params + run script), cutting token usage 10-20x.
/browser-script <platform> <action-description>
/browser-script linkedin "edit a comment to append link text"
/browser-script reddit "post a reply to a comment"
/browser-script linkedin "extract post data from search results"
Before writing code, manually walk through the flow in the target browser agent to discover:
browser_snapshot)getByRole)browser_network_requests)Create scripts/<action>_<platform>.js following this skeleton:
// action_platform.js — One-line description
// Runs inside {platform}-agent browser via browser_run_code.
//
// Params via window.__params:
// { field1: "...", field2: "..." }
//
// Returns: { ok: true, ...data } or { ok: false, error: "error_code" }
async (page) => {
const params = await page.evaluate(() => window.__params);
if (!params || !params.requiredField) {
return JSON.stringify({ ok: false, error: 'missing_params' });
}
try {
// Step 1: Navigate
await page.goto(params.url, { waitUntil: 'domcontentloaded', timeout: 30000 });
await page.waitForTimeout(3000);
// Step 2: Scroll to load content
await page.evaluate(() => window.scrollBy(0, 1500));
await page.waitForTimeout(2000);
// Step 3: Find element (with retry after scroll)
const element = page.getByRole('button', { name: /pattern/i }).first();
try {
await element.waitFor({ timeout: 10000 });
} catch {
await page.evaluate(() => window.scrollBy(0, 2000));
await page.waitForTimeout(2000);
try {
await element.waitFor({ timeout: 5000 });
} catch {
return JSON.stringify({ ok: false, error: 'element_not_found' });
}
}
// Step 4: Interact
await element.click();
await page.waitForTimeout(1000);
// Step 5: Verify
return JSON.stringify({ ok: true, result: 'done' });
} catch (e) {
return JSON.stringify({ ok: false, error: e.message });
}
}
Test in two calls:
// Set params
mcp__{platform}-agent__browser_run_code code:
async (page) => {
await page.evaluate(() => {
window.__params = { url: "...", text: "..." };
});
}
// Run script
mcp__{platform}-agent__browser_run_code filename:
~/social-autoposter/scripts/the_script.js
If it fails, take a browser_snapshot to debug, fix the script, re-test.
Replace the Claude prompt instructions for this flow with the 2-call pattern. Example from engage.sh Phase D LinkedIn:
# Old: 8-line prompt telling Claude to navigate, find comment, click menu, edit, save
# New:
8. For LinkedIn: use the edit script via linkedin-agent browser:
a. Set params: browser_run_code with code setting window.__params
b. Run: browser_run_code with filename=$REPO_DIR/scripts/edit_linkedin_comment.js
c. Parse JSON result: {ok:true} = success, {ok:false, error} = handle error
Params via window.__params — never hardcode. Script must be reusable across different targets.
Return JSON always — {ok: true, ...data} or {ok: false, error: "code"}. Error codes are specific and actionable: comment_not_found, link_already_present, not_logged_in, save_failed, element_not_found.
Script owns all waits — waitForTimeout, waitFor, scroll-retry loops. Caller just runs and reads result.
keyboard.type() not fill() — React-based sites (LinkedIn, possibly Twitter) don't detect fill() changes. Always keyboard.type() for rich text editors. For full text replacement: click({clickCount: 3}) + Meta+a + keyboard.type(newText).
Scroll before find — social platforms lazy-load. Always scroll into view before locating elements.
Locate by role/name — page.getByRole('button', {name: /pattern/i}) not CSS class selectors. Survives redesigns.
One script = one complete action — "edit a comment", "scan notifications", "post a reply". Not a single click. Not an entire engagement loop.
Safety checks inside the script — dedup detection (link already present, already replied). Don't rely on the caller.
Generous timeouts — social sites are slow. Use 3s after navigation, 2s after scroll, 1s after click.
Two-phase element finding — first try with 10s timeout, then scroll more and retry with 5s. Return specific error if still not found.
The split: Claude decides WHAT (pick project, write text, choose targets). Scripts execute HOW (navigate, click, type, save).
fill() won't trigger change detectiontextbox[name="Text editor for creating comment"] after clicking Editbutton[name=/View more options for Matthew/i]fetch() for read-only operations (notifications)mcp__linkedin-agent__browser_run_codemcp__reddit-agent__browser_run_codemcp__twitter-agent__browser_run_code| Script | Platform | Action | Params |
|--------|----------|--------|--------|
| scan_linkedin_notifications.js | LinkedIn | Read notifications via internal API | none (uses cookies) |
| edit_linkedin_comment.js | LinkedIn | Append text to our comment | {postUrl, appendText} |
Full design doc: scripts/BROWSER_SCRIPTS.md
tools
End-to-end workflow for creating, rebuilding, or enhancing a client's website. Covers SEO audit, content extraction, Next.js scaffolding, real image/video assets, structured data, SEO guide pages, component injection, analytics, deployment, and dashboard registration. Includes concrete design system blueprints with exact Tailwind classes, component templates, and section layouts. Use when: 'create client website', 'rebuild website', 'recreate site', 'client landing page', 'SEO pages for client', or when onboarding a new client who needs a web presence.
tools
End-to-end workflow for creating, rebuilding, or enhancing a client's website. Covers SEO audit, content extraction, Next.js scaffolding, real image/video assets, structured data, SEO guide pages, component injection, analytics, deployment, and dashboard registration. Includes concrete design system blueprints with exact Tailwind classes, component templates, and section layouts. Use when: 'create client website', 'rebuild website', 'recreate site', 'client landing page', 'SEO pages for client', or when onboarding a new client who needs a web presence.
tools
Set up social-autoposter for a new user. Interactive wizard that installs via npm, creates the database, configures accounts, verifies browser logins, and optionally sets up scheduled automation. Use when: 'set up social autoposter', 'install social autoposter', 'configure social posting'.
testing
Automate social media posting across Reddit, X/Twitter, LinkedIn, and Moltbook. Find threads, post comments, create original posts, track engagement stats. Use when: 'post to social', 'social autoposter', 'find threads to comment on', 'create a post', 'audit social posts', 'update post stats', or after completing any task (mandatory per CLAUDE.md).